プロジェクトの中で複数カメラの同期を撮って録画するスクリプトを作成することになりました
ffmpegで頑張って作ったのですが、今思えばGStreamerで作れば簡単だったのではと後悔してます
というよりNVIDIA MetropolisのVideo Wallでなんか仕込めればよかった
Usage & Configuration — mdx-docs 2.1 documentation
調査項目
Webカメラ仕様
- 同じUSBハブに複数カメラを接続しても一つのカメラしか起動しない(No space left on device {デバイスパス} と表示され起動しない)
RAW動画のメリット・デメリット
- Webカメラで取得したそのままの動画をRAW動画という。
- メリットとしては、エンコードしない分高品質である、撮影時の設定や編集後の調整において柔軟、編集にも適している。
- デメリットとしては、サイズが大きいまま、コンピュータの処理が高いものになる、そのままでは再生できない。
エンコードとは
- 我々が普段扱っているmp4等の動画ファイルは映像データと音声データを格納したフォルダのようなものまとまりである
- それを圧縮したり視聴可能な形に変換する作業をエンコードという
- 変換後のデータをコンテナというフォルダのようなものに入れている
圧縮動画のメリット・デメリット
- MP4やmovなどコーデックが使用された(エンコードされた)動画
- メリットとしては、ファイルサイズが小さい、広くサポートされるため再生しやすい。
- デメリットとしては、圧縮した分の品質低下、編集時の制約、色の破綻が起きやすい。
コーデックとは
- エンコードするためのプログラムのこと
- 映像はH.264, H.265, MPEG-4等がある
- 音声はMP4, AAC, WMA等がある
フォーマットとは
- エンコード後の動画ファイルの形式
- MP4, AVI, MOV等がある
カメラのFPSと録画時のFPS
- 揃えましょう
最初動画のFPS設定はしていましたが、カメラ側のFPS設定を決められることを知らず揃えてませんでした
FPSが揃ってないと動画のコマ数がずれてしまい動画がカクカクしたりと影響があるようです
接続遅延をなくすための手法
- 録画開始までの待機時間を設ける
Health Checkみたいなのがあればいいんですがね、見つからなかったです
作ったスクリプト
- 供養のため貼っておきます
完全版がどこかにあったはずなのですが見つからずプロトタイプになります
また、実行していた端末では綺麗に撮れていたのですが、スペックがメモリ64GB、GPUがA6000とハイスペック、Webカメラとの接続が有線だったりしたため参考にならんかもです
#!/bin/bash
# カメラのRTSP URLリストを配列に定義
CAMERA_URLS=(
"rtsp://camera1_address/stream"
"rtsp://camera2_address/stream"
"rtsp://camera3_address/stream"
"rtsp://camera4_address/stream"
"rtsp://camera5_address/stream"
"rtsp://camera6_address/stream"
)
# 各カメラのバッファリングを開始
for i in ${!CAMERA_URLS[@]}; do
ffmpeg -i "${CAMERA_URLS[$i]}" -f mpegts "udp://localhost:1234$i" &
echo "Camera $((i+1)) buffering started on udp://localhost:1234$i"
done
# 少し待機して、接続が確立される時間を与える
sleep 5
echo "===========Recording Start==========="
# 各カメラの録画を開始
for i in ${!CAMERA_URLS[@]}; do
ffmpeg -i "udp://localhost:1234$i" -t 60 -c copy -f mp4 \
"camera$((i+1))_output.mp4" </dev/null > /dev/null 2>&1 &
echo "Camera $((i+1)) recording started to camera$((i+1))_output.mp4"
done
# すべての録画プロセスが終了するまで待機
wait
echo "All recordings completed."
