OpenCVでH264を使う為の環境構築

## 概要

OpenCVでH264を使用したいがネットに落ちている情報が分かりづらかったのでとりあえず
以下のフローで行えます。またPython環境にも使えるようにしています。


## 用意するもの:

以下のソースをビルドします。

- OpenH264: 2.5.1
- ffmpeg: n4.3.9
- OpenCV contrib: 4.11.0
- OpenCV: 4.11.0

Pythonにビルド済みのOpenCVをいれるにはnumpyを事前に入れておきます。

- numpy: 2.2.5

## 手順：

### OpenH264のビルド

```bash
export OPENH_264_VER="2.5.1"
curl -LO https://github.com/cisco/openh264/archive/refs/tags/${OPENH_264_VER}.tar.gz \
  && tar -xvzf ${OPENH_264_VER}.tar.gz \
  && cd openh264-${OPENH_264_VER} \
  && make -j4 \
  && make install
```

### FFMPEGのビルド
今回の環境はCPUのみなので以下の様な設定しています。
またOpenH264を使用する為、libx264はdisableにしています。
```bash
export FFMPEG_VER="n4.3.9"
curl -LO https://github.com/FFmpeg/FFmpeg/archive/refs/tags/${FFMPEG_VER}.tar.gz \
  && tar -xvzf ${FFMPEG_VER}.tar.gz \
  && cd FFmpeg-${FFMPEG_VER} \
  && ./configure \
  --enable-shared \
  --enable-gpl \
  --disable-libx264 \
  --enable-libaom \
  --enable-nonfree \
  --enable-libopenh264 \
  --enable-optimizations \
  --enable-static \
  --enable-version3 \
  --disable-logging \
  --disable-doc \
  --disable-htmlpages \
  --disable-manpages \
  --disable-podpages \
  --disable-txtpages \
  --disable-avdevice \
  --disable-postproc \
  --disable-bzlib \
  --disable-iconv \
  --disable-cuda \
  --disable-cuvid \
  --disable-debug \
  && make -j4 \
  && make install \
  && ldconfig \
  && rm /tmp/${FFMPEG_VER}.tar.gz
```

### OpenCV contribをダウンロード:

こいつはDLするだけOpenCVビルド時に必要。

```bash
export OPENCV_CONTRIB_VER="4.11.0"
curl -LO https://github.com/opencv/opencv_contrib/archive/refs/tags/${OPENCV_CONTRIB_VER}.tar.gz \
  && tar -xvzf ${OPENCV_CONTRIB_VER}.tar.gz
```

その為、パスは変数などに入れておいてください。

```bash
export OPENCV_CONTRIB_MODULE=/tmp/opencv_contrib-${OPENCV_CONTRIB_VER}/modules
```

### OpenCVのビルド

> 注意：この段階でNumpyがPythonの環境にインストールされている必要があります。

pythonの環境値を洗い出します。
```bash
export PYTHON_EXEC="/usr/local/bin/python3"
# python3 -c "from sysconfig import get_paths as gp; print(gp()['include'])"
export PYTHON_INCLUDE="/usr/local/include/python3.11"
# python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
export PYTHON_SITE="/usr/local/lib/python3.11/site-packages"
# python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"
export PYTHON_LIB="/usr/local/lib"
```

ビルドとインストールは以下の様にします。

```bash
export OPENCV_VER="4.11.0"
export INSTALL_DIR="/usr/local"
curl -LO https://github.com/opencv/opencv/archive/refs/tags/${OPENCV_VER}.tar.gz \
  && tar -xvzf ${OPENCV_VER}.tar.gz \
  && cd opencv-${OPENCV_VER} \
  && mkdir build \
  && cd build \
  && cmake \
    -DCMAKE_BUILD_TYPE=RELEASE \
    -DOPENCV_EXTRA_MODULES_PATH=${OPENCV_CONTRIB_MODULE} \
    -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
    -DOPENCV_PYTHON_INSTALL_PATH=${PYTHON_SITE} \
    -DPYTHON3_EXECUTABLE=${PYTHON_EXEC} \
    -DPYTHON_DEFAULT_EXECUTABLE=${PYTHON_EXEC} \
    -DPYTHON3_INCLUDE_DIR=${PYTHON_INCLUDE} \
    -DPYTHON3_LIBRARY=${PYTHON_LIB}/libpython3.11.so \
    -DPYTHON3_PACKAGES_PATH=${PYTHON_SITE} \
    -DFFMPEG_INCLUDE_DIR=/usr/local/include/ \
    -DFFMPEG_LIB_DIR=/usr/local/lib/ \
    -DOPENCV_FFMPEG_USE_FIND_PACKAGE=OFF \
    -DHAVE_opencv_python2=OFF \
    -DHAVE_opencv_python3=ON \
    -DBUILD_opencv_python2=OFF \
    -DBUILD_opencv_python3=ON \
    -DWITH_OPENH264=ON \
    -DBUILD_DOCS=OFF \
    -DBUILD_TESTS=OFF \
    -DBUILD_EXAMPLES=OFF \
    -DBUILD_JAVA=OFF \
    -DWITH_1394=OFF \
    -DWITH_CUDA=OFF \
    -DWITH_CUFFT=OFF \
    -DWITH_FFMPEG=ON \
    -DWITH_GSTREAMERE=OFF \
    -DWITH_GTK=OFF \
    -DWITH_IPP=OFF \
    -DWITH_JASPERE=OFF \
    -DWITH_JPEG=ON \
    -DWITH_OPENEXR=OFF \
    -DWITH_PNG=ON \
    -DWITH_TIFF=ON \
    -DWITH_V4L=OFF \
    -DWITH_GPHOTO2=OFF \
    -DWITH_CUBLAS=OFF \
    -DWITH_VTK=OFF \
    -DWITH_NVCUVID=OFF \
    .. \
  && make -j4 \
  && make install \
  && ldconfig
```

以上となります。

## 確認
以下の様にChatGPTで作成したコード実行し動作を確認。
次のようなログが出ますが、これは`H264`指定では無く`avc1`にしろよと言われているみたいですが、問題なくH264で動画作成されている事が確認できると思います。


```bash
OpenCV: FFMPEG: tag 0x34363248/'H264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
```

#### サンプルコード

```python
import cv2
import numpy as np

# 動画ファイルのパス
output_file = "output.mp4"

# フレームの設定
width, height = 640, 480
fps = 30

# 動画のフォーマット（avc1を使用）
fourcc = cv2.VideoWriter_fourcc(*'H264')

# VideoWriterを初期化
out = cv2.VideoWriter(output_file, fourcc, fps, (width, height))

# フレームの作成と書き込み（例として単純な白いフレームを作成）
for _ in range(300):  # 10秒間の動画（30fps x 10秒）
    frame = np.ones((height, width, 3), dtype=np.uint8) * 255  # 白いフレーム
    out.write(frame)

# 動画の書き込み終了
out.release()

print(f"動画 {output_file} を作成しました。")
```