Transcoding Live Simple Filtergraphs¶
What are Simple filtergraphs?
Before heading straight into recipes we will talk about Simple filtergraphs:
Simple filtergraphs are those filters that have exactly one input and output, both of the same type.
They can be processed by simply inserting an additional step between decoding and encoding of video frames:
Simple filtergraphs are configured with the per-stream -filter
option (with -vf
for video).
DeFFcode's FFdecoder API handles a single chain of filtergraphs (through
-vf
FFmpeg parameter) to the to real-time frames quite effortlessly.
We'll discuss the transcoding of live simple filtergraphs in the following recipes:
DeFFcode APIs requires FFmpeg executable
DeFFcode APIs MUST requires valid FFmpeg executable for all of its core functionality, and any failure in detection will raise RuntimeError
immediately. Follow dedicated FFmpeg Installation doc ➶ for its installation.
Additional Python Dependencies for following recipes
Following recipes requires additional python dependencies which can be installed easily as below:
-
OpenCV: OpenCV is required for previewing and encoding video frames. You can easily install it directly via
pip
:OpenCV installation from source
You can also follow online tutorials for building & installing OpenCV on Windows, Linux, MacOS and Raspberry Pi machines manually from its source.
Make sure not to install both pip and source version together. Otherwise installation will fail to work!
Other OpenCV binaries
OpenCV maintainers also provide additional binaries via pip that contains both main modules and contrib/extra modules
opencv-contrib-python
, and for server (headless) environments likeopencv-python-headless
andopencv-contrib-python-headless
. You can also install any one of them in similar manner. More information can be found here.
Always use FFdecoder API's terminate()
method at the end to avoid undesired behavior.
OpenCV's' VideoWriter()
class lacks the ability to control output quality, bitrate, compression, and other important features which are only available with VidGear's WriteGear API.
Transcoding Trimmed and Reversed video¶
In this example we will take the first 5 seconds of a video clip (using trim
filter) and reverse it (by applying reverse
filter), and encode them using OpenCV Library's VideoWriter()
method in real-time.
The reverse
filter requires memory to buffer the entire clip, so applying trim
filter first is strongly recommended. Otherwise you might probably run Out of Memory.
OpenCV's VideoWriter()
class requires a valid Output filename (e.g. output_foo.avi), FourCC code, framerate, and resolution as input.
You can use FFdecoder's metadata
property object that dumps source Video's metadata information (as JSON string) to retrieve output framerate and resolution.
By default, OpenCV expects BGR
format frames in its write()
method.
# import the necessary packages
from deffcode import FFdecoder
import json, cv2
# define the Video Filter definition
# trim 5 sec from end and reverse
ffparams = {
"-vf": "trim=end=5,reverse"
}
# initialize and formulate the decoder for BGR24 output with given params
decoder = FFdecoder(
"foo.mp4", frame_format="bgr24", verbose=True, **ffparams
).formulate()
# retrieve JSON Metadata and convert it to dict
metadata_dict = json.loads(decoder.metadata)
# prepare OpenCV parameters
FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
FRAMERATE = metadata_dict["output_framerate"]
FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
# Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():
# check if frame is None
if frame is None:
break
# {do something with the frame here}
# writing BGR24 frame to writer
writer.write(frame)
# terminate the decoder
decoder.terminate()
# safely close writer
writer.release()
Transcoding Cropped video¶
In this example we will crop real-time video frames by an area with size ⅔ of the input video (say foo.mp4
) by applying crop
filter in FFdecoder API, all while encoding them using OpenCV Library's VideoWriter()
method in real-time.
OpenCV's VideoWriter()
class requires a valid Output filename (e.g. output_foo.avi), FourCC code, framerate, and resolution as input.
You can use FFdecoder's metadata
property object that dumps source Video's metadata information (as JSON string) to retrieve output framerate and resolution.
More complex examples using crop
filter can be found here ➶ and can be applied similarly.
# import the necessary packages
from deffcode import FFdecoder
import json, cv2
# define the Video Filter definition
# cropped the central input area with size 2/3 of the input video
ffparams = {
"-vf": "crop=2/3*in_w:2/3*in_h"
}
# initialize and formulate the decoder for BGR24 output with given params
decoder = FFdecoder(
"foo.mp4", frame_format="bgr24", verbose=True, **ffparams
).formulate()
# retrieve JSON Metadata and convert it to dict
metadata_dict = json.loads(decoder.metadata)
# prepare OpenCV parameters
FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
FRAMERATE = metadata_dict["output_framerate"]
FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
# Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():
# check if frame is None
if frame is None:
break
# {do something with the frame here}
# writing BGR24 frame to writer
writer.write(frame)
# terminate the decoder
decoder.terminate()
# safely close writer
writer.release()
Transcoding Rotated video (with rotate
filter)¶
FFmpeg features Rotate Filter that is used to rotate videos by an arbitrary angle (expressed in radians).
In this example we will rotate real-time video frames at an arbitrary angle by applying rotate
filter in FFdecoder API and also using green color to fill the output area not covered by the rotated image, all while encoding them using OpenCV Library's VideoWriter()
method in real-time.
OpenCV's VideoWriter()
class requires a valid Output filename (e.g. output_foo.avi), FourCC code, framerate, and resolution as input.
You can use FFdecoder's metadata
property object that dumps source Video's metadata information (as JSON string) to retrieve output framerate and resolution.
# import the necessary packages
from deffcode import FFdecoder
import json, cv2
# define the Video Filter definition
# rotate by 0.35 rad and fill green
ffparams = {
"-vf": "rotate=angle=-20*PI/180:fillcolor=green"
}
# initialize and formulate the decoder for BGR24 output with given params
decoder = FFdecoder(
"foo.mp4", frame_format="bgr24", verbose=True, **ffparams
).formulate()
# retrieve JSON Metadata and convert it to dict
metadata_dict = json.loads(decoder.metadata)
# prepare OpenCV parameters
FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
FRAMERATE = metadata_dict["output_framerate"]
FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
# Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():
# check if frame is None
if frame is None:
break
# {do something with the frame here}
# writing BGR24 frame to writer
writer.write(frame)
# terminate the decoder
decoder.terminate()
# safely close writer
writer.release()
Transcoding Rotated video (with transpose
filter)¶
FFmpeg also features Transpose Filter that is used to rotate videos by 90 degrees clockwise and counter-clockwise direction as well as flip them vertically and horizontally.
In this example we will rotate real-time video frames by 90 degrees counterclockwise and preserve portrait geometry by applying transpose
filter in FFdecoder API, all while encoding them using OpenCV Library's VideoWriter()
method in real-time.
OpenCV's VideoWriter()
class requires a valid Output filename (e.g. output_foo.avi), FourCC code, framerate, and resolution as input.
You can use FFdecoder's metadata
property object that dumps source Video's metadata information (as JSON string) to retrieve output framerate and resolution.
# import the necessary packages
from deffcode import FFdecoder
import json, cv2
# define the Video Filter definition
# rotate by 90 degrees counter-clockwise and preserve portrait layout
ffparams = {
"-vf": "transpose=dir=2:passthrough=portrait"
}
# initialize and formulate the decoder for BGR24 output with given params
decoder = FFdecoder(
"foo.mp4", frame_format="bgr24", verbose=True, **ffparams
).formulate()
# retrieve JSON Metadata and convert it to dict
metadata_dict = json.loads(decoder.metadata)
# prepare OpenCV parameters
FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
FRAMERATE = metadata_dict["output_framerate"]
FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
# Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():
# check if frame is None
if frame is None:
break
# {do something with the frame here}
# writing BGR24 frame to writer
writer.write(frame)
# terminate the decoder
decoder.terminate()
# safely close writer
writer.release()
Transcoding Horizontally flipped and Scaled video¶
In this example we will horizontally flip and scale real-time video frames to half its original size by applying hflip
and scale
filter one-by-one in FFdecoder API, all while encoding them using OpenCV Library's VideoWriter()
method in real-time.
OpenCV's VideoWriter()
class requires a valid Output filename (e.g. output_foo.avi), FourCC code, framerate, and resolution as input.
You can use FFdecoder's metadata
property object that dumps source Video's metadata information (as JSON string) to retrieve output framerate and resolution.
More complex examples using scale
filter can be found here ➶ and can be applied similarly.
# import the necessary packages
from deffcode import FFdecoder
import json, cv2
# define the Video Filter definition
# horizontally flip and scale to half its original size
ffparams = {
"-vf": "hflip,scale=w=iw/2:h=ih/2"
}
# initialize and formulate the decoder for BGR24 output with given params
decoder = FFdecoder(
"foo.mp4", frame_format="bgr24", verbose=True, **ffparams
).formulate()
# retrieve JSON Metadata and convert it to dict
metadata_dict = json.loads(decoder.metadata)
# prepare OpenCV parameters
FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
FRAMERATE = metadata_dict["output_framerate"]
FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
# Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():
# check if frame is None
if frame is None:
break
# {do something with the frame here}
# writing BGR24 frame to writer
writer.write(frame)
# terminate the decoder
decoder.terminate()
# safely close writer
writer.release()