3

I am on Ubuntu 18.04, but the solution has to generalize to Debian Buster because that's what Streamlit.io Sharing websites runs on.

I want to write frames with Python OpenCV to a h.264 encoded mp4 file.

It has to be h.264 so that it can be shown on the web, and it has to be mp4 because it's the most common video file type.

I am struggling to find a FOURCC code that works for these exact requirements. The code goes here:

out = cv2.VideoWriter(output_name, cv2.VideoWriter_fourcc(*'X264'), fps, insize)

I have tried avc1 and avc3, which yield Could not find encoder for codec_id=27, error: Encoder not found

Note that avc1 works fine on Windows when the cisco-provided file openh264-1.8.0-win64.dll is in the same directory as the python file, but having the Linux equivalent libopenh264-1.8.0-linux64.so does not make it work on Ubuntu.

H264 and X264 fail with 'H264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)'

I have installed ffmpeg, x264, and libx264-dev with sudo apt-get install, but they do not change the outcome whatsover as the comment on here here says.

One possible lead I have is to compile ffmpeg with 264 enabled, but I'm unfamiliar and I'm not confident I could replicate it on Streamlit, since I can't just ssh in and run commands.

Is it just impossible to encode h.264 on mp4 on Linux with Python OpenCV? This seems like it should be doable, but I've hit many dead ends.

8
  • I've come across this blog that seems to have come to a similar conclusion to me, that compiling stuff manually ( or with Docker ) is the solution: swiftlane.com/blog/… I'm holding out hope for a better solution, since I'm not sure Docker will work with Streamlit Sharing.
    – kevinlinxc
    Commented Aug 14, 2021 at 2:08
  • Use MP4V forcc code
    – Micka
    Commented Aug 14, 2021 at 6:09
  • @Micka MP4V does not work as the resulting video can't be seen on websites ( No video with supported format and MIME type found.)
    – kevinlinxc
    Commented Aug 14, 2021 at 7:50
  • 1
    use PyAV instead. gives you more flexibility. and it's not such an ugly hack as calling ffmpeg as a subprocess and moving video data through pipes. example code: github.com/PyAV-Org/PyAV/blob/main/examples/numpy/… Commented Aug 14, 2021 at 10:45
  • 1
    PyAV does exactly what I want. Calling ffmpeg with os.system to convert opencv's mp4v to h.264 also worked, but required double the processing time so naturally using PyAV was better. Copying code from this issue was sufficient to solve my problem: github.com/PyAV-Org/PyAV/issues/471, it was more specific than @ChristophRackwitz's example because it uses bgr and h.264, but much appreciated for the solution
    – kevinlinxc
    Commented Aug 14, 2021 at 20:13

0

Browse other questions tagged or ask your own question.