🧅

H.264対応のopencv-pythonのwheelをマルチステージビルドする

2024/12/22に公開

はじめに

先日、「opencv-pythonのwheelを並列ビルドしてビルド時間を5分の1にした」という記事を書きました。

https://zenn.dev/yuyakato/articles/0c6782411031b1

H.264対応のopencv-pythonパッケージを素早く手に入れたかったがゆえに書いた記事ですが、並列ビルドでビルド時間を短縮した後も約5分とそれなりの時間が掛かってしまいます。
Dockerイメージのビルドキャッシュが効かない状況(依存関係の変更など)が生じる度に5分待つのはしんどいので、マルチステージビルドを活用して、wheelのビルドを分離することにしました。

ビルド済みopencv-python-headlessパッケージ

H.264対応のopencv-python-headlessパッケージ(opencv-pythonのヘッドレス版)をビルドする前に、比較対象としてH.264に対応していないビルド済みバイナリ(pip install opencv-python-headlessでインストールされるもの)を使って動作を確認しました。

Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY ./requirements.txt ./
RUN --mount=type=cache,mode=0755,sharing=locked,target=/root/.cache/pip \
  python -m pip install --requirement requirements.txt
requirements.txt
numpy==2.2.0
opencv-python-headless==4.10.0.84
build_info.py
import pathlib

import cv2

pathlib.Path("build_info.txt").write_text(cv2.getBuildInformation())
make_video.py
import sys

import cv2
import numpy as np

fourcc = sys.argv[1]
width, height = 640, 480
fps = 30

video_writer = cv2.VideoWriter(
    f"{fourcc}.mp4", cv2.VideoWriter_fourcc(*fourcc), fps, (width, height)
)

for _ in range(30):
    frame = np.random.randint(0, 255, (height, width, 3), dtype=np.uint8)
    video_writer.write(frame)

video_writer.release()

上記のDocker環境、Pythonスクリプトを使って動作を確認してみます。

$ python build_info.py
$ python make_video.py mp4v
$ python make_video.py avc1
[ERROR:0@0.009] global cap_ffmpeg_impl.hpp:3133 open Could not find encoder for codec_id=27, error: Encoder not found
[ERROR:0@0.009] global cap_ffmpeg_impl.hpp:3211 open VIDEOIO/FFMPEG: Failed to initialize VideoWriter

コーデックにavc1(H.264の別名)を指定したところ、エラーになってしまいました。まあ、想定通りですが。

出力されたbuild_info.txtは以下の通りです。(長いので折りたたんでいます)

build_info.txtの内容
build_info.txt
General configuration for OpenCV 4.10.0 =====================================
  Version control:               4.10.0

  Platform:
    Timestamp:                   2024-06-17T17:56:36Z
    Host:                        Linux 5.15.0-1064-azure x86_64
    CMake:                       3.29.5
    CMake generator:             Unix Makefiles
    CMake build tool:            /bin/gmake
    Configuration:               Release

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (16 files):         + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (0 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (8 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (36 files):           + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
      AVX512_SKX (5 files):      + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX

  C/C++:
    Built as dynamic libs?:      NO
    C++ standard:                11
    C++ Compiler:                /opt/rh/devtoolset-10/root/usr/bin/c++  (ver 10.2.1)
    C++ flags (Release):         -Wl,-strip-all   -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
    C++ flags (Debug):           -Wl,-strip-all   -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
    C Compiler:                  /opt/rh/devtoolset-10/root/usr/bin/cc
    C flags (Release):           -Wl,-strip-all   -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -Wl,-strip-all   -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
    Linker flags (Release):      -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a -L/ffmpeg_build/lib  -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    Linker flags (Debug):        -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a -L/ffmpeg_build/lib  -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    ccache:                      YES
    Precompiled headers:         NO
    Extra dependencies:          /lib64/libopenblas.so /usr/local/lib/libpng.so /lib64/libz.so dl m pthread rt
    3rdparty dependencies:       libprotobuf ade ittnotify libjpeg-turbo libwebp libtiff libopenjp2 IlmImf ippiw ippicv

  OpenCV modules:
    To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo python3 stitching video videoio
    Disabled:                    world
    Disabled by dependency:      -
    Unavailable:                 java python2 ts
    Applications:                -
    Documentation:               NO
    Non-free algorithms:         NO

  GUI:                           NONE
    VTK support:                 NO

  Media I/O:
    ZLib:                        /lib64/libz.so (ver 1.2.7)
    JPEG:                        build-libjpeg-turbo (ver 3.0.3-70)
      SIMD Support Request:      YES
      SIMD Support:              YES
    WEBP:                        build (ver encoder: 0x020f)
    PNG:                         /usr/local/lib/libpng.so (ver 1.6.43)
    TIFF:                        build (ver 42 - 4.6.0)
    JPEG 2000:                   build (ver 2.5.0)
    OpenEXR:                     build (ver 2.3.0)
    HDR:                         YES
    SUNRASTER:                   YES
    PXM:                         YES
    PFM:                         YES

  Video I/O:
    DC1394:                      NO
    FFMPEG:                      YES
      avcodec:                   YES (59.37.100)
      avformat:                  YES (59.27.100)
      avutil:                    YES (57.28.100)
      swscale:                   YES (6.7.100)
      avresample:                NO
    GStreamer:                   NO
    v4l/v4l2:                    YES (linux/videodev2.h)

  Parallel framework:            pthreads

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Intel IPP:                   2021.11.0 [2021.11.0]
           at:                   /io/_skbuild/linux-x86_64-3.9/cmake-build/3rdparty/ippicv/ippicv_lnx/icv
    Intel IPP IW:                sources (2021.11.0)
              at:                /io/_skbuild/linux-x86_64-3.9/cmake-build/3rdparty/ippicv/ippicv_lnx/iw
    VA:                          NO
    Lapack:                      YES (/lib64/libopenblas.so)
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.19.1)
    Flatbuffers:                 builtin/3rdparty (23.5.9)

  OpenCL:                        YES (no extra features)
    Include path:                /io/opencv/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python 3:
    Interpreter:                 /opt/python/cp39-cp39/bin/python3.9 (ver 3.9.19)
    Libraries:                   libpython3.9m.a (ver 3.9.19)
    Limited API:                 YES (ver 0x03060000)
    numpy:                       /home/ci/.local/lib/python3.9/site-packages/numpy/_core/include (ver 2.0.0)
    install path:                python/cv2/python-3

  Python (for build):            /opt/python/cp39-cp39/bin/python3.9

  Java:
    ant:                         NO
    Java:                        NO
    JNI:                         NO
    Java wrappers:               NO
    Java tests:                  NO

  Install to:                    /io/_skbuild/linux-x86_64-3.9/cmake-install
-----------------------------------------------------------------

また、出力されたmp4v.mp4ffprobeの結果は以下の通りです。

$ ffprobe -hide_banner mp4v.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'mp4v.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 28959 kb/s
  Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 28951 kb/s, 30 fps, 30 tbr, 15360 tbn, 30 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]

H.264対応opencv-python-headlessパッケージ

本題のマルチステージビルドに入りましょう。
少々長くなってしまいましたが、できあがったDockerfileは以下の通りです。依存Debianパッケージはもう少し整理できるかもしれません。
opencv-baseステージが依存Debianパッケージのインストール用、opencvステージがwheelのビルド用、無名ステージが実際のアプリケーション用です。
なお、通常版(非ヘッドレス版)をビルドするためにはもう少し依存Debianパッケージが増えますが、私はヘッドレス版ばかり使っているので未検討です。

Dockerfile
FROM python:3.11-slim AS opencv-base
RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \
  --mount=type=cache,sharing=locked,target=/var/lib/apt \
  rm -f /etc/apt/apt.conf.d/docker-clean \
  && apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
    build-essential \
    cmake \
    libavcodec-dev \
    libavformat-dev \
    libopencv-dev \
    libopenexr-dev \
    libpng-dev \
    libssl-dev \
    libswscale-dev \
    libtiff-dev \
    libturbojpeg0-dev \
    libwebp-dev \
    libx264-dev
ENV OPENCV_PYTHON_VERSION 4.10.0.84

FROM opencv-base AS opencv
RUN --mount=type=cache,mode=0755,sharing=locked,target=/root/.cache/pip \
  python -m pip install \
    build==1.2.2.post1 \
    packaging==24.2 \
    pyproject_hooks==1.2.0
WORKDIR /root
RUN --mount=type=cache,mode=0755,sharing=locked,target=/root/.cache/pip \
  python -m pip download --no-binary opencv-python-headless opencv-python-headless==${OPENCV_PYTHON_VERSION}
RUN tar zxfv opencv-python-headless-${OPENCV_PYTHON_VERSION}.tar.gz
RUN cd opencv-python-headless-${OPENCV_PYTHON_VERSION}/ \
  && MAKEFLAGS="-j$(nproc)" python -m build --wheel
RUN mkdir /dist \
  && cp opencv-python-headless-${OPENCV_PYTHON_VERSION}/dist/opencv_python_headless-*.whl /dist/

FROM opencv-base
COPY --from=opencv /dist/opencv_python_headless-*.whl /root/
WORKDIR /app
COPY ./requirements.txt ./
RUN --mount=type=cache,mode=0755,sharing=locked,target=/root/.cache/pip \
  python -m pip install --requirement requirements.txt
requirements.txt
numpy==2.2.0
opencv-python-headless @ file:///root/opencv_python_headless-4.10.0.84-cp311-cp311-linux_x86_64.whl

ビルド済み版と同様、上記のDocker環境を使って動作を確認してみます。

$ python build_info.py
$ python make_video.py mp4v
$ python make_video.py avc1

今度はmp4vavc1共に正常に出力されました。

出力されたbuild_info.txtは以下の通りです。(長いので折りたたんでいます)
ビルド済み版とあまり差が出ないようにビルドしたつもりですが、JPEG関係など、細かな違いはあります。

build_info.txtの内容
build_info.txt
General configuration for OpenCV 4.10.0 =====================================
  Version control:               unknown

  Platform:
    Timestamp:                   2024-12-18T10:00:40Z
    Host:                        Linux 5.15.0-126-generic x86_64
    CMake:                       3.31.2
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/gmake
    Configuration:               Release

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (16 files):         + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (0 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (8 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (36 files):           + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
      AVX512_SKX (5 files):      + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX

  C/C++:
    Built as dynamic libs?:      NO
    C++ standard:                11
    C++ Compiler:                /usr/bin/c++  (ver 12.2.0)
    C++ flags (Release):         -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
    C++ flags (Debug):           -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
    C Compiler:                  /usr/bin/cc
    C flags (Release):           -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
    Linker flags (Release):      -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    Linker flags (Debug):        -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    ccache:                      NO
    Precompiled headers:         NO
    Extra dependencies:          /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/x86_64-linux-gnu/libwebp.so /usr/lib/x86_64-linux-gnu/libpng.so /usr/lib/x86_64-linux-gnu/libtiff.so /usr/lib/x86_64-linux-gnu/libz.so dl m pthread rt
    3rdparty dependencies:       libprotobuf ade ittnotify libopenjp2 IlmImf ippiw ippicv

  OpenCV modules:
    To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo python3 stitching video videoio
    Disabled:                    world
    Disabled by dependency:      -
    Unavailable:                 java python2 ts
    Applications:                -
    Documentation:               NO
    Non-free algorithms:         NO

  GUI:                           NONE
    VTK support:                 NO

  Media I/O:
    ZLib:                        /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.13)
    JPEG:                        /usr/lib/x86_64-linux-gnu/libjpeg.so (ver 62)
    WEBP:                        /usr/lib/x86_64-linux-gnu/libwebp.so (ver encoder: 0x020f)
    PNG:                         /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.6.39)
    TIFF:                        /usr/lib/x86_64-linux-gnu/libtiff.so (ver 42 / 4.5.0)
    JPEG 2000:                   build (ver 2.5.0)
    OpenEXR:                     build (ver 2.3.0)
    HDR:                         YES
    SUNRASTER:                   YES
    PXM:                         YES
    PFM:                         YES

  Video I/O:
    DC1394:                      YES (2.2.6)
    FFMPEG:                      YES
      avcodec:                   YES (59.37.100)
      avformat:                  YES (59.27.100)
      avutil:                    YES (57.28.100)
      swscale:                   YES (6.7.100)
      avresample:                NO
    GStreamer:                   NO
    v4l/v4l2:                    YES (linux/videodev2.h)

  Parallel framework:            pthreads

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Intel IPP:                   2021.11.0 [2021.11.0]
           at:                   /root/opencv-python-headless-4.10.0.84/_skbuild/linux-x86_64-3.11/cmake-build/3rdparty/ippicv/ippicv_lnx/icv
    Intel IPP IW:                sources (2021.11.0)
              at:                /root/opencv-python-headless-4.10.0.84/_skbuild/linux-x86_64-3.11/cmake-build/3rdparty/ippicv/ippicv_lnx/iw
    VA:                          NO
    Lapack:                      NO
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.19.1)
    Flatbuffers:                 builtin/3rdparty (23.5.9)

  OpenCL:                        YES (no extra features)
    Include path:                /root/opencv-python-headless-4.10.0.84/opencv/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python 3:
    Interpreter:                 /tmp/build-env-aog3lu_n/bin/python (ver 3.11.11)
    Libraries:                   /usr/local/lib/libpython3.11.so (ver 3.11.11)
    Limited API:                 YES (ver 0x03060000)
    numpy:                       /tmp/build-env-aog3lu_n/lib/python3.11/site-packages/numpy/_core/include (ver 2.2.0)
    install path:                python/cv2/python-3

  Python (for build):            /tmp/build-env-aog3lu_n/bin/python

  Java:
    ant:                         NO
    Java:                        NO
    JNI:                         NO
    Java wrappers:               NO
    Java tests:                  NO

  Install to:                    /root/opencv-python-headless-4.10.0.84/_skbuild/linux-x86_64-3.11/cmake-install
-----------------------------------------------------------------

また、出力されたmp4v.mp4avc1.mp4ffprobeの結果は以下の通りです。
avc1.mp4はちゃんとH.264になっていますね。

$ ffprobe -hide_banner mp4v.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'mp4v.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 28964 kb/s
  Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 28956 kb/s, 30 fps, 30 tbr, 15360 tbn, 30 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]

$ ffprobe -hide_banner avc1.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'avc1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 32737 kb/s
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 32729 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]

なお、pip freezeするとopencv-python-headless @ file:///...#sha256=...というハッシュ値付きの行が生成されますが、ビルドする度にハッシュ値は変わってしまうため、ハッシュ値の部分は削除することをオススメします。

おわりに

VSCodeに内蔵されている動画プレビュー機能は、avc1には対応しているけれどmp4vには対応しておらずプレビューできない…ということをきっかけに並列ビルド、マルチステージビルドに取り組みました。

並列ビルド、マルチステージビルドを活用することで、より快適にH.264対応のopencv-python-headlessパッケージを使えるようになりました。
Dockerfileが少々長くなり、初回のビルドには時間が掛かりますが、ビルド済みバイナリを管理する手間もなく、手軽に利用できる点が個人的には気に入っています。

本記事が何らかの参考になれば幸いです。

Discussion