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:23000and in the secondffmpeg -i sample.mp4 -vcodec mpeg4 -f mpegts udp://127.0.0.1:23000. This should play the videosample.mp4although 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 mpegtsas output options. Tip: Adding-v 0to ffmpeg sets the global log level to zero. By default, ffmpeg can be rather verbose. -vcodec mpeg4sets 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 mpegtsforces 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
-reto stream files at their native rate. Otherwise, they will play too fast. - Add
-b:v 500kor 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.sdp8 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