gstreamer
audioとvideo をくっつけるテスト
マルチプレクサというのを使うらしい
他のエンコード例
gst-inspect-1.0
testsrcから映像と音声をくっつけてQuickTime Muxかけてファイルに書き出す例
code:bash
gst-launch-1.0 -e videotestsrc ! video/x-raw,width=1280,height=720,framerate=60/1,bitrate=500000 ! queue ! muxer.video_0 audiotestsrc wave=sine freq=1000 ! audio/x-raw,format=S16LE,layout=interleaved,rate=48000,channels=2 ! voaacenc ! queue ! muxer.audio_0 qtmux name="muxer" ! filesink location=/tmp/rec.mp4
kmssink は video/x-raw だけに対応しているのかな
HDMIの音声出力がalsaとして見えるので、そこに対してalsasinkで投げてやれば良いみたい
code:bash
gst-launch-1.0 alsasrc device=hw:UAC1Gadget ! alsasink device=hw:0,0
書き捨てスクリプトメモ
rpicamsrc から来た映像と音声をHDMI接続のディスプレイに流すやつ
code:bridge.sh
gst-launch-1.0 rpicamsrc preview=false ! \
video/x-raw,width=1280,height=720,framerate=60/1,bitrate=500000 ! \
kmssink &
gst-launch-1.0 alsasrc device=hw:UAC1Gadget ! alsasink device=hw:0,0
rpicamsrc から来た映像と音声をHDMI接続ディスプレイに流す & 映像をsdpでリモートに流すやつ
code:bridge-and-sdp.sh
gst-launch-1.0 rpicamsrc preview=false ! \
video/x-raw,width=1280,height=720,framerate=30/1,bitrate=500000 ! \
tee name=t t. ! queue ! kmssink t. ! \
omxh264enc ! \
h264parse ! rtph264pay config-interval=-1 pt=96 ! \
udpsink host=whywaita.local port=5678 &
gst-launch-1.0 alsasrc device=hw:UAC1Gadget ! alsasink device=hw:0,0
結局↑のようにkmssinkを使ってブリッジさせるのは辞めた @ 2020/07
kmssinkだとRPi4の処理性能の都合上解像度が微妙に下がってしまうため
v4l2 デバイスとして動作させる
mzyy94のブログを見るに、rpicamsrcを使っていると再接続時にうまく動作しないということがあるとあった。実際に手元でも似たような事象が発生したのでv4l2デバイスで扱うようにする。
code:play.sh
gst-launch-1.0 --gst-debug-level=3 --verbose --messages v4l2src device=/dev/video0 ! \
video/x-raw,width=1024,height=768,framerate=30/1,format=UYVY ! \
v4l2h264enc extra-controls="encode,h264_profile=1,h264_level=12;" ! \
video/x-h264,stream-format=byte-stream,profile=constrained-baseline ! \
h264parse config-interval=-1 ! \
rtph264pay pt=96 ! \
udpsink host=whywaita.local port=5678
--gst-debug-level=3 --verbose --messages でデバッグ表示が出来る
どこまで送信できているかの確認ができる
v4l2-ctl --device /dev/video0 --all でどういうフォーマットで映像が出力されているかを見ることができる
code:bash
Format Video Capture:
Width/Height : 1024/768
Pixel Format : 'UYVY' (UYVY 4:2:2)
Field : None
Bytes per Line : 2048
Size Image : 1572864
Colorspace : SMPTE 170M
Transfer Function : Default (maps to Rec. 709)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization : Default (maps to Limited Range)
Flags :
↑の出力から 1024x768 解像度で UYVY 形式で出力しているということが分かる
デバイスが出力しているデータと違うような解像度で出力すると映像が荒れてしまう
このためにcap filter ( video/x-raw,width=1024,height=768,framerate=30/1,format=UYVY ) を仕込む
macOSのディスプレイ解像度変更機能を使って1080pにするとやはり荒れた映像になった、なんでだろう…
ディスプレイがどのような解像度であるかはEDIDをディスプレイ側が送信して、映像元がその映像を出力する
ただmzyy94が提供している720p 30FPSのファイルでうまく認識されていないっぽい(上記のように1024x768になってしまう)ので恐らくうまく適用できていない。
再接続に関してはHDMIを抜き差し後gst-launchコマンドを再起動するとちゃんと動く模様
同じボードを使って遊んでいる人も居る
HDMI経由で音声を取得できないか試行錯誤しているようだがまだ無理そうだ
PW-HT225P-IR を使って分岐していたのがうまくいっていなかったが、直接Switchに刺すとうまく動作した (2020/08) v4l2-ctl --set-edid=file=720P30EDID.txt --device /dev/video0 deviceの指定は忘れないように
分岐しているのでディスプレイ側のEDIDを処理しているのかもしれない?
1366x768 なので上記の1024x768とは縦は一致する
code:bash
$ v4l2-ctl --set-edid=file=720P30EDID.txt --device /dev/video0
$ v4l2-ctl --all --device /dev/video0
Format Video Capture:
Width/Height : 1280/720
Pixel Format : 'UYVY' (UYVY 4:2:2)
Field : None
Bytes per Line : 2560
Size Image : 1843200
Colorspace : SMPTE 170M
Transfer Function : Default (maps to Rec. 709)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization : Default (maps to Limited Range)
Flags :
$ cat play.sh
gst-launch-1.0 --gst-debug-level=3 --verbose --messages v4l2src device=/dev/video0 ! \
video/x-raw,width=1280,height=720,framerate=30/1 ! \
v4l2h264enc extra-controls="encode,h264_profile=1,h264_level=12;" ! \
video/x-h264,stream-format=byte-stream,profile=constrained-baseline ! \
h264parse config-interval=-1 ! \
rtph264pay pt=96 ! \
udpsink host=whywaita.local port=5678
便利コマンド
gst-device-monitor-1.0 繋がっているデバイスが確認できる
RaspberryOSなら gstreamer1.0-plugins-base-apps パッケージに入っている