Swiftlane

Generating MP4’s Using opencv-python With the AVC1 Codec

Updated:

This article is about a rabbit-hole I recently went down, no there will not be any Mad-Hatters or talking cats just video codecs and build flags. The task I was trying to complete seemed simple enough: Use OpenCV to generate a working MP4 video by concatenating frames. Originally I attempted the following and got the error below:

>>> import cv2
>>>
>>> fourcc = cv2.VideoWriter_fourcc(*"avc1")
>>> video_writer = cv2.VideoWriter("movie.mp4", fourcc, 5, (5,5))
Could not find encoder for codec id 27: Encoder not found

For licensing reasons ,opencv-python does not ship with some of the more common video codecs. The first solution I tried initially was to change the codec to mp4v with the following change.

fourcc = cv2.VideoWriter_fourcc(*"mp4v")

Problem solved! Let’s go out for some drinks, right? Not so fast. Unfortunately, MP4V is not supported by most browsers, a fact I learned when I tried to embed one of these videos in a web application. After going down the rabbit hole for a while, I realized that the solution would involve compiling some of the sources manually. I could not find a comprehensive step-by-step solution, so I had to combine instructions from different sources. Below is the Dockerfile for my working image. Before you use it here are some things to know:

  • opencv-python is already installed on this image, if you re-install opencv-python using pip, it will break.
  • I have gotten the avc1 codec working for MP4 files, in order to use x264 or h264 I had to change the file extension to .mkv (If you know how to fix this let me know in the comments).

FROM ubuntu:18.04

WORKDIR /root

ENV OPENCV_VERSION=4.3.0 \
PYTHON_VERSION=3.6 \
PYTHON_VERSION_SHORT=36

RUN apt-get update
RUN apt-get remove -y ffmpeg x264 libx264-dev

RUN apt-get install -y \
build-essential \
cmake \
libjack-jackd2-dev \
libmp3lame-dev \
libopencore-amrnb-dev \
libopencore-amrwb-dev \
libsdl1.2-dev \
libtheora-dev \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libx11-dev \
libxfixes-dev \
libxvidcore-dev \
texi2html \
zlib1g-dev \
wget \
unzip \
yasm \
pkg-config \
libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libavformat-dev \
python${PYTHON_VERSION} \
python3-pip \
libpq-dev

RUN apt-get remove -y x264 ffmpeg libx264-dev && \
apt-get install -y x264 libx264-dev && \
apt-get install -y ffmpeg && \
pip3 install numpy

RUN wget https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip && \
unzip ${OPENCV_VERSION}.zip && \
mkdir opencv-${OPENCV_VERSION}/build

WORKDIR /root/opencv-${OPENCV_VERSION}/build

RUN cmake \
-DBUILD_TIFF=ON \
-DBUILD_opencv_java=OFF \
-DWITH_CUDA=OFF \
-DWITH_OPENGL=ON \
-DWITH_OPENCL=ON \
-DWITH_IPP=ON \
-DWITH_TBB=ON \
-DWITH_EIGEN=ON \
-DWITH_V4L=ON \
-DBUILD_TESTS=OFF \
-DBUILD_PERF_TESTS=OFF \
-DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=$(python${PYTHON_VERSION} -c "import sys; print(sys.prefix)") \
-DPYTHON_EXECUTABLE=$(which python${PYTHON_VERSION}) \
-DPYTHON_INCLUDE_DIR=$(python${PYTHON_VERSION} -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-DPYTHON_PACKAGES_PATH=$(python${PYTHON_VERSION} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
-DPYTHON_DEFAULT_EXECUTABLE=$(which python${PYTHON_VERSION}) \
-DBUILD_NEW_PYTHON_SUPPORT=ON \
-DBUILD_opencv_python3=ON \
-DHAVE_opencv_python3=ON \
-DBUILD_opencv_gapi=OFF \
-DPYTHON3_NUMPY_INCLUDE_DIRS=/usr/local/lib/python${PYTHON_VERSION}/dist-packages/numpy/core/include \
.. \
&& make install

RUN mv \
/root/opencv-${OPENCV_VERSION}/build/lib/python3/cv2.cpython-${PYTHON_VERSION_SHORT}m-x86_64-linux-gnu.so \
/usr/local/lib/python${PYTHON_VERSION}/dist-packages/cv2.so

RUN unlink /usr/bin/python && ln -s /usr/bin/python3 /usr/bin/python

WORKDIR /root

RUN apt clean && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /root/opencv-${OPENCV_VERSION}

Subscribe to the Multifamily Newsletter

Get the latest news and updates in multifamily and commercial real estate.

Loading the secure form…

Read more