Search code examples
pythonffmpegtimestampwebcam

Capture webcam using ffmpeg-python library


Hi I'm attempting to capture a webcam stream with python using the ffmpeg-python wrapper library (https://github.com/kkroening/ffmpeg-python) I have a working ffmpeg command which is:

ffmpeg -f v4l2 -video_size 352x288 -i /dev/video0 -vf "drawtext='fontfile=fonts/FreeSerif.ttf: text=%{pts} : \
x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1'" -an -y -t 15 videotests/out_localtime8.mp4

This captures 15s of video in resolution 352x288, and writes a timestamp in the bottom centre of the video.

To play with the ffmpeg-python library, I'm simply attempting to only get the drawtext filter working, here is my script:

#!/usr/bin/env python

import ffmpeg
stream = ffmpeg.input('videotests/example.mov')
stream = ffmpeg.filter_(stream,'drawtext',("fontfile=fonts/FreeSerif.ttf:text=%{pts}"))
stream = ffmpeg.output(stream, 'videotests/output4.mp4')
ffmpeg.run(stream)

The error is

[Parsed_drawtext_0 @ 0x561f59d494e0] Either text, a valid file or a timecode must be provided
[AVFilterGraph @ 0x561f59d39080] Error initializing filter 'drawtext' with args 'fontfile\\\=fonts/FreeSerif.ttf\\\:text\\\=%{pts}'
Error initializing complex filters.
Invalid argument

The above appears to at least reach ffmpeg but the format of the arguments is incorrect, how to correct them?

Alternatively, when I attempting to split the argument to just pass one of them, I get a different error, as follows:

stream = ffmpeg.filter_(stream,'drawtext',('text=%{pts}'))

Error is

subprocess.CalledProcessError: Command '['ffmpeg', '-i', 'videotests/example.mov', '-filter_complex', "[0]drawtext=(\\\\\\\\\\\\\\'text\\\\\\\\\\\\=%{pts}\\\\\\\\\\\\\\'\\,)[s0]", '-map', '[s0]', 'videotests/output4.mp4']' returned non-zero exit status 1.

How come there are so many backslashes? Any advice on how to proceed please.

Thank you


Solution

  • I worked out the correct syntax eventually. Here is a working example

    #!/usr/bin/env python
    
    import ffmpeg
    stream = ffmpeg.input('videotests/example.mov')
    stream = ffmpeg.filter_(stream,'drawtext',fontfile="fonts/hack/Hack-Regular.ttf",text="%{pts}",box='1', boxcolor='0x00000000@1', fontcolor='white')
    stream = ffmpeg.output(stream, 'videotests/output6.mp4')
    ffmpeg.run(stream)
    

    The syntax is

    ffmpeg.filter_(<video stream name>,'<filter name>',filter_parameter_name='value',<filter_parameter_name>=value)
    

    Where necessary use quotes for the filter_parameter_name values.

    Hope this helps someone.