Skip to content

Instantly share code, notes, and snippets.

@docPhil99
Last active August 25, 2020 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save docPhil99/899c4180447f52f4d5d6d66534ee7800 to your computer and use it in GitHub Desktop.
Save docPhil99/899c4180447f52f4d5d6d66534ee7800 to your computer and use it in GitHub Desktop.
Streaming FFmpeg and Python

This is running on Linux Mint

  1. Install ffmpeg
sudo apt-get install ffmpeg
  1. A simple test: open two terminals, in first run ffplay udp://127.0.0.1:23000 and in the second ffmpeg -i sample.mp4 -vcodec mpeg4 -f mpegts udp://127.0.0.1:23000 . This should play the video sample.mp4 although the quality is rather blocky.
  2. 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.
  3. -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.
  4. Add -re to stream files at their native rate. Otherwise, they will play too fast.
  5. 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

  1. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment