This is running on Linux Mint
- Install ffmpeg
sudo apt-get install ffmpeg
- A simple test: open two terminals, in first run
ffplay udp://127.0.0.1:23000
and in the secondffmpeg -i sample.mp4 -vcodec mpeg4 -f mpegts udp://127.0.0.1:23000
. This should play the videosample.mp4
although the quality is rather blocky. - The command line format is
ffpeg [global options] {[input options] -i input_url} {[output options] output_url}
. So here we have no input options, and-vcodec mpeg4 -f mpegts
as output options. Tip: Adding-v 0
to ffmpeg sets the global log level to zero. By default, ffmpeg can be rather verbose. -vcodec mpeg4
sets the ouput codec to Mpeg4 part 2, we can improve on this with Mpeg4 part 10 or H.264. Change it to-vcodec libx264
.-f mpegts
forces the output format to be mpegts. Usually, this option is not needed since it can be guessed for the output file extension. However, we have not specified one here.- Add
-re
to stream files at their native rate. Otherwise, they will play too fast. - Add
-b:v 500k
or a higher number to the output options to control the bitrate. Or you can try-crf 30
. This sets the Content Rate Factor. That's an x264 argument that tries to keep reasonably consistent video quality, while varying bitrate A value of 30 allows somewhat lower quality and bit rate.
Complete list of options - offsite
- With udp we still get lost packets. Instead try rtsp over tcp
ffmpeg -stream_loop 5 -re -i OxfordStreet.avi -vf scale=320:240 -vcodec libx264 -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:23000/live.sdp
8 To read this in python:
import numpy as np
import cv2
import ffmpeg #ffmpeg-python
in_file='rtsp://127.0.0.1:23000/live.sdp?tcp'#?overrun_nonfatal=1?buffer_size=10000000?fifo_size=100000'
# ffmpeg -stream_loop 5 -re -i OxfordStreet.avi -vcodec libx264 -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:23000/live.sdp
width = 320
height = 240
cv2.namedWindow("test")
process1 = (
ffmpeg
.input(in_file,rtsp_flags= 'listen')
.output('pipe:', format='rawvideo', pix_fmt='bgr24')
.run_async(pipe_stdout=True)
)
while True:
in_bytes = process1.stdout.read(width * height * 3)
if not in_bytes:
break
in_frame = (
np
.frombuffer(in_bytes, np.uint8)
.reshape([height, width, 3])
)
cv2.imshow("test", in_frame)
cv2.waitKey(10)
process1.wait()
See Also
Hi @ktosiu,
Is this possible to take multiple mpegts input from ffmpeg like bit-rate specific and pass it to a third party program. What I want to achieve is:
ffmpeg -i original.mkv -c:v h264 -c:a aac -f mpegts - | myprogam \\ -c:v h264 -c:a aac -vf "scale=1280:720" -f mpegts - | myprogam \\ -c:v h264 -c:a aac -vf "scale=854:480" -f mpegts - | myprogam \\
This command will not work but can explain my requirement. Is there any alternative to do this with a single command.
I tried python threading but in that case I have to run multiple ffmpeg command.
Any help is highly appreciated.
Thank you