Reading and writing audio and video batchs from/to audio and video file using ffmpeg backend
Project description
simple-ffmpeg-batch-io
Reading and writing image and audio batches from/to video and audio files using an FFmpeg backend, with a simple Python API built on top of numpy.
Features
- Read batches of audio and video frames from video and audio files into
numpyarrays. - Write batches of frames from
numpyarrays to video or audio files, even compressed - Uses
static_ffmpegto provide FFmpeg binaries in a portable way. Simple-ffmpeg-batch-io provide ffmpeg and ffprobe as commands within the virtual environment - Designed for machine learning and audio/video generation pipelines.
Installation of last version
pip install simple-ffmpeg-batch-io
Documentation
Automatically generated documentation is available online.
Examples
Handling video files (i.e. images from video files)
Read video file at its own frame rate and frame shape
# Open it with VideoIO old way (C++ style)
inputVideo = VideoIO()
inputVideo.open(video_filename) # video file is a str or a path
# or open it a more pythonish way
inputVideo = VideoIO.reader(video_filename) # video file is a str or a path
# Here, one can read inputVideo.width, inputVideo.height, inputVideo.fps
print(inputVideo.width, inputVideo.height, inputVideo.fps)
# read one frame
frame = inputVideo.read_frame() # Here frame is a numpy arrays of shape (Width,height,channels). Channel is 3 as we support only 3 channels for the moment.
# Process video frame by frame
for frame in inputVideo.iter_frames():
# Process frame. Here frame is a numpy arrays of shape (Width,height,channels). Channel is 3 as we support only 3 channels for the moment.
process( frame )
# or process video using batches
n = 10
for batch in inputVideo.iter_batches(n):
# Process batch. Here batch is a numpy arrays of shape (n,Width,height,channels). Channel is 3 as we support only 3 channels for the moment.
process( batch )
inputVideo.close()
# Read video frame by frame with associated timestamps using with context, no need to close after end of context, close is aotomùatically called.
with VideoIO.reader(video_filename) as inputVideo:
for frame in inputVideo.iter_frames(with_timestamps = True):
# Here frame is encapsulated within simple-ffmpeg-batch-io.FrameContainer object
process( frame.data ) # numpy array of shape (Width,height,channels)
print( frame.timestamps ) # python list of the timestamp associated to the frame (video here, but same for audio), here only one element as one frame is used
# OR
# Read video batch by batch with associated timestamps using with context, no need to close after end of context, close is aotomùatically called.
n = 10
with VideoIO.reader(video_filename) as inputVideo:
for batch in inputVideo.iter_batches(n, with_timestamps = True):
# Here batch is encapsulated within simple-ffmpeg-batch-io.FrameContainer object
process( batch.data ) # numpy array of shape (n,Width,height,channels)
print( batch.timestamps ) # python list of timestamps associated to each frame (video here, but same for audio), here only one element as one frame is used
Read video file with more parameters
from simple_ffmpeg_batch_io import VideoIO
# Read video changing width, height, and fps
inputVideo = VideoIO.reader(video_file, width=100, height=100, fps=1.0)
# Read modifying only some of them
with VideoIO.reader(video_file, width=100, fps=2.0) as inputVideo:
...
Read video and write video file with dedicated ffmpeg parameters
from simple_ffmpeg_batch_io import VideoIO
# open file using filter:
# resizing to width=320, adapting height to keep aspect ratio while keep height pair (for some codec like H264)
# pixelising it to 5x5 pixels
# important note: one must not use decodingParams for scalling. Indeed, VideoIO class use filter to scale video, use width/height parameters
with VideoIO.reader(video_in_filename, width=320, height=320, decodingParams="-vf pixelize=w=5:h=5") as inputVideo,
VideoIO.writer(video_out_filename, width=inputVideo.width, height=inputVideo.height, fps=inputVideo.fps ) as outputVideo: # possible to add encodingParams to add filters, ...
# iter over batch of 10s and write it to the output file
batch_size = int( 10*inputVideo.fps )
for batch in inputVideo.iter_batches(batch_size):
outputVideo.write_batch(batch)
Handling audio from video or audio files
Read audio from audio file
from simple_ffmpeg_batch_io import AudioIO
# Read audio converting it to one channel, 16000 Hz, frame size of 1s as parameter is a float, start reading file at 2.0s
# default mode is plannar, i.e. samples are not interleaved, they are separated by channel after reading
# frame_size for subsequent call to read_frame, iter_frames, read_batch or iter_batches is 1.0s (16000 samples) as the value is a float, thus times in seconds.
inputAudio = AudioIO.reader(audio_filename, sample_rate=16000, channels=1, frame_size = 1.0, start_time = 2.0 )
# Read batches of 10 audio frames, each frame has 16000 sanples (1.0 second)
for audio_batch in inputAudio.iter_batches(10):
... # audio_batch is a np.array
# OR
# If the frame_size value is an int, frame_size is considered as a number of samples, for instance to have 0.5 seconds at 16 Khz (8000 samples for each frame)
with AudioIO.reader(audio_filename, sample_rate=16000, channels=1, frame_size = 8000, start_time = 2.0 ) as inputAudio:
# Read batches of 10 audio frames, each frame has 8000 sanples
for audio_batch in inputAudio.iter_batches(10, with_timestamps = True):
.... # audio_batch is encapsulated within a FrameContainer object with_timestamps = True
Copy audio stream(s) from an audio file or a video file with an audio stream to a wav file
from simple_ffmpeg_batch_io import AudioIO
# Read audio data in interleaved mode (plannard = False) to avoid useless conversion to plannar using default frame_size (1 second). Sample rate remains the same.
with AudioIO.reader(audio_or_video_filename, plannar = False) as inputAudio:
# Copy sample_rate and channels to the created file, overwrite existing output filename if any.
with AudioIO.writer(audio_filename, sample_rate=inputAudio.sample_rate, channels=inputAudio.channels, plannar = False, writeOverExistingFile = True) as outputAudio:
# Read batches of 10 audio frames (10 seconds as frame_size was by default 1 second when opening video)
for audio_batch in inputAudio.iter_batches(10):
outputAudio.write_batch(audio_batch)
# no need to close AudioIO objects as 'with' context do it automatically.
Static utility functions
VideoIO
from simple_ffmpeg_batch_io import VideoIO
# get (width, height, fps) of a video using a static function
print( VideoIO.get_params(video_filename) )
# get length of an audio stream as float (seconds.milliseconds)
print( VideoIO.get_time_in_sec(video_filename) )
AudioIO
from simple_ffmpeg_batch_io import AudioIO
# get (channels,sample_rate) of a stream using astatic function
print( AudioIO.get_params(audio_or_video_filename) )
# get length of video stream as float (seconds.milliseconds)
print( AudioIO.get_time_in_sec(audio_or_video_filename) )
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simple_ffmpeg_batch_io-1.1.0.tar.gz.
File metadata
- Download URL: simple_ffmpeg_batch_io-1.1.0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64fd93cd303c459e55eaf1191047f3cd716920fb6fcfa7b2398d4d341bd5e4fd
|
|
| MD5 |
624e9c4e60096855b441f67932bcb184
|
|
| BLAKE2b-256 |
a818314c18af522d1a026862177fd2e695811cb95b0fb17c507efcf4ac510a4a
|
File details
Details for the file simple_ffmpeg_batch_io-1.1.0-py3-none-any.whl.
File metadata
- Download URL: simple_ffmpeg_batch_io-1.1.0-py3-none-any.whl
- Upload date:
- Size: 28.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d7c65d2dd9575231d0b45496f90256ab3fca03a6356154d044690f9c664bcdc
|
|
| MD5 |
2f02389e11da38486d2bf0a67b05c45f
|
|
| BLAKE2b-256 |
e2f015a81570bbda7f7520df8ccfe534c7cf0ddaa8ccd8e91d2c64235fbba38e
|