🌟

sora-cpp-sdk-samplesでカメラの映像をローカルに録画しつつWebRTCで送信する

2022/07/04に公開

前回の応用
https://zenn.dev/tetsu_koba/articles/6d4d9b47b808c8

pipe_video_srcを使うと何かのプロセスでI420のビデオデータを生成できればそれをWebRTCで送信できます。
今回はgstreamerでカメラの映像を取り出し2つに分岐させ、片方をエンコードして録画し、もう片方をI420に変換して pipe_video_srcにくわせています。
音声は無しです。

#!/bin/sh -eux

SIGNALING_URL=wss://207-148-110-182.canary.sora.sora-labo.shiguredo.app/signaling
CHANNEL_ID=tetsu-koba@sora-devtools
SIGNALING_KEY=xxxyyy
WIDTH=1280
HEIGHT=720
FRAMERATE=30

AUDIO_OPT='--no-audio-device'

RECDIR=$PWD/rec
MAX_FILE_SIZE=$((100 * 1024 * 1024))
MAX_FILES=20

filename="$RECDIR/d%04d.m2ts"
index_wrap=10000
last_index=`ls -t $RECDIR/d[0-9]*.m2ts |head -1 |sed -n -e 's/\.m2ts$//' -e 's/[^0-9]//gp'`
if [ -z $last_index ] ; then
    mkdir -p $RECDIR
    next_index=0
else
    next_index=`echo "($last_index + 1) % $index_wrap" |bc`
fi
touch $RECDIR/start_${next_index}_$(date +%Y%m%d%H%M%S)

FIFO=$PWD/.fifo
rm -f $FIFO
mkfifo $FIFO

./pipe_video_src --log-level 1 $AUDIO_OPT --video-fifo $FIFO --resolution ${WIDTH}x${HEIGHT} --framerate $FRAMERATE \
     --signaling-url $SIGNALING_URL --channel-id $CHANNEL_ID \
     --multistream true --video-codec-type H264 \
     --metadata "{\"signaling_key\": \"$SIGNALING_KEY\"}" > log 2>&1 &

gst-launch-1.0 -eq v4l2src device="/dev/video0" ! \
    "image/jpeg, width=$WIDTH, height=$HEIGHT, framerate=$FRAMERATE/1" ! \
    tee name = t \
    t. ! queue2 ! nvv4l2decoder mjpeg=1 ! 'video/x-raw(memory:NVMM)' ! \
        nvvidconv ! 'video/x-raw, format=(string)I420' ! \
        filesink location=$FIFO blocksize=1048576 \
    t. ! queue2 ! nvv4l2decoder mjpeg=1 ! 'video/x-raw(memory:NVMM)' ! \
        nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420' ! \
        nvv4l2h265enc insert-sps-pps=1 iframeinterval=60 bitrate=2000000 ! \
        h265parse ! mpegtsmux ! multifilesink location=$filename index=$next_index \
        next-file=4 max-file-size=$MAX_FILE_SIZE max-files=$MAX_FILES

gstreamerのところを以下のように書くとmjpegのデコードを2重に行わなくて済むのでよさそうですが、サイズの大きなI420のデータをteeでコピーすることになるせいか、WebRTCで送信したときの遅延時間が長くなってしまいました。

gst-launch-1.0 -eq v4l2src device="/dev/video0" ! \
    "image/jpeg, width=$WIDTH, height=$HEIGHT, framerate=$FRAMERATE/1" ! \
    nvv4l2decoder mjpeg=1 ! 'video/x-raw(memory:NVMM)' ! \
    nvvidconv ! 'video/x-raw, format=(string)I420' ! \
    tee name = t \
    t. ! queue2 ! filesink location=$FIFO blocksize=1048576 \
    t. ! queue2 ! nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420' ! \
        nvv4l2h265enc insert-sps-pps=1 iframeinterval=60 bitrate=2000000 ! \
        h265parse ! mpegtsmux ! multifilesink location=$filename index=$next_index \
        next-file=4 max-file-size=$MAX_FILE_SIZE max-files=$MAX_FILES

関連

https://zenn.dev/tetsu_koba/articles/6d4d9b47b808c8
https://zenn.dev/tetsu_koba/articles/26b4fc43387322

Discussion