GStreamer を色々弄ってるけどどんどんカオスな状態になっていくのでメモっとく。
「もう OpenMAX 対応したし ffmpeg でいいじゃん!」とは言ってはいけない。
YouTube Live に艦隊これくしょんのプレイ動画をストリーミング配信
艦隊これくしょんに限らず、画面の一部分を切り出してストリーミング配信するのでデュアルディスプレイの片方を配信用として使ったりすることもできる。サンプルではテキスト描画や HD 化などのも入れてあるので少々長い。
YouTube に「キーフレーム間隔長すぎんぞ」って言われるけどどこを弄ればいいのかわからない。(omxh264enc にそんなパラメータあるの?)
パラメータはまだ調整中。
ximagesrc xname="艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES"
と指定すると艦これのウィンドウだけを拾ってくる(アクティブの場合のみ録画する?)。このウィンドウ名は xwininfo
で調べられる。
Raspberry Pi & OpenMAX
- omxh264enc は x264enc に比べてオプションが少なく、
gst-inspect-1.0 omxh264enc
を読んでもわかりづらい target-bitrate=
はcontrol-rate=
が無いと使えない- プロパティの値は
0x00000000
〜0xffffffff
がデフォルトのようなのでprintf
で10進数に変換させている target-bitrate=
に0x01000000
以上は指定できない(?)- alsasrc はチャンネルを指定しないとモノラルになる
- このサンプルでは VNC サーバを 16-bit で起動しているので
ximagesrc
の出力が RGB16 になっているが 24-bit で起動しておいた方が良さそう
gst-launch-1.0 -v -e \ flvmux streamable=true name=m ! rtmpsink sync=false location="rtmp://a.rtmp.youtube.com/live2/hvd4-k0rb-xp1p-e3ua" \ ximagesrc display-name=:0 show-pointer=false startx=$x starty=$y endx=$((x+800-1)) endy=$((y+480-1)) \ ! videoconvert ! video/x-raw, framerate=24000/1001 \ ! videoscale ! video/x-raw, width=1280, height=720, pixel-aspect-ratio=1/1, method=0 \ ! textoverlay font-desc="Droid Sans 8" draw-outline=false shaded-background=true valignment=top halignment=left text="Raspberry Pi 3 - `uname -srm`" \ ! timeoverlay font-desc="Droid Sans" draw-outline=false shaded-background=true valignment=bottom halignment=right \ ! videoconvert ! omxh264enc control-rate=variable target-bitrate=$(printf '%d' 0x00ffffff) ! h264parse config-interval=4 ! queue ! m. \ alsasrc buffer-time=$((1*1000*1000)) ! audio/x-raw, channels=2 ! faac ! aacparse ! queue ! m.
X86_64 & VAAPI
艦これの画面は800×480ピクセルだが、720p に変換して YouTube Live に投げる。H.264 への変換は VAAPI を使うことで負荷を少なくする。H.264 への変換はデバイスによってハードウェアエンコードが可能だが、それぞれ名称やプロパティが異なるのでネットを徘徊して情報を集める場合は予めその辺に注意しておく必要がある。(例えば Raspberry Pi なら omxh264enc
)
PulseAudio のデバイスが正しく選択されない場合は pavucontrol
を使うことで GUI でデバイスを変更することができる。
gst-launch-1.0 -e \ flvmux name=m ! rtmpsink sync=false location="rtmp://a.rtmp.youtube.com/live2/STREAM-KEY" \ ximagesrc display-name=:0 startx=${x} starty=${y} endx=$((x+800-1)) endy=$((y+480-1)) show-pointer=false \ ! video/x-raw, framerate=30/1 \ ! videoscale ! video/x-raw, width=1280, height=720, pixel-aspect-ratio=1/1 \ ! textoverlay font-desc="Droid Sans" halignment=left valignment=top shaded-background=true text="$(set -- $(lscpu | grep "^Model name:"); shift 2; echo $*)" \ ! timeoverlay font-desc="Droid Sans" halignment=right valignment=bottom shaded-background=true \ ! videoconvert ! video/x-raw, format=YV12 \ ! vaapih264enc rate-control=cbr bitrate=$((4*1024)) cabac=true max-bframes=2 ! queue ! m. \ pulsesrc volume=1 buffer-time=1000000 \ ! audio/x-raw, format=S16LE, rate=44100, channels=2 ! voaacenc ! aacparse ! queue ! m.
Screen Shot & Interval/Time Lapse
スナップショットとして1枚記録する。
gst-launch-1.0 ximagesrc ! videoconvert ! pngenc snapshot=true compression-level=9 ! filesink location=screenshot.png
毎秒撮影。
gst-launch-1.0 ximagesrc ! video/x-raw, framerate=1/1 ! videoconvert ! pngenc snapshot=false compression-level=9 ! multifilesink location=%04d.png
エンコード
multifilesrc
を使って複数の画像ファイルを入力に指定する。入力タイプおよびフレームレートは caps=
で指定する。ポイントとしては PNG をエンコーダの入力形式に合うよう正しく変換すること(ここでは sRGB から I420 の変換を行っている)。進捗が確認できないので ffmpeg で変換した方がいいかもしれない。
gst-launch-1.0 multifilesrc location="%04d.png" index=0 caps="image/png, framerate=5/1" ! pngdec ! videoconvert ! video/x-raw, format=I420 ! vaapih264enc ! qtmux ! filesink location=video.mp4
音楽 CD の再生と取り込み
mode=1
はディスク全体を指定するcdda://{TRACK}
またはtrack=
を指定しなかった場合のデフォルトは1
cdda://
書式ではmode=
が指定できない(?)
再生
■ cdda プロトコルによる再生
(内部的に cdparanoiasrc を呼び出してる?)
gst-inspect-1.0 cdda:// ! autoaudiosink
gst-inspect-1.0 cdda://3 ! autoaudiosink
■ cdiocddasrc による再生
gst-inspect-1.0 cdiocddasrc mode=1 ! autoaudiosink gst-inspect-1.0 cdiocddasrc track=3 ! autoaudiosink
■ cdparanoiasrc による再生
gst-inspect-1.0 cdparanoiasrc mode=1 ! autoaudiosink gst-inspect-1.0 cdparanoiasrc track=3 ! autoaudiosink
■ スペクトラグラム 付きで再生する
tee
を使って1つを autoaudiosink
へ。もう1つを audioconvert
を通して spectrascope
に投げる。
gst-launch-1.0 cdparanoiasrc ! \ tee ! queue ! autoaudiosink \ tee0. ! queue ! audioconvert ! spectrascope shader=8 ! video/x-raw, width=640, height=480 ! ximagesink
上の例に更にエンコード(ファイル保存)を追加すると以下のようになる。
gst-launch-1.0 cdparanoiasrc track=3 ! \ tee ! queue ! autoaudiosink \ tee0. ! queue ! audioconvert ! spectrascope shader=8 ! video/x-raw, width=640, height=480 ! ximagesink \ tee0. ! queue ! filesink location=track03.wav
WAV エンコード
gst-launch-1.0 cdparanoiasrc track=1 ! wavenc ! filesink location=track01.wav
DOT ファイルの出力と変換
GST_DEBUG_DUMP_DOT_DIR=
が設定されていれば指定されたディレクトリに DOT ファイルが作成される。
GST_DEBUG_DUMP_DOT_DIR=. gst-launch-1.0 [PIPELINE-DESCRIPTION]
Graphviz の dot
コマンドでも変換できるけど、サイズの指定ができないようなので ImageMagick を使う。フォント名は DOT ファイルに直書きされているので sed などで好みのものに変換する。
仮にこのファイルを dotconv.sh
とする。
#!/bin/bash sed 's|fontname="sans"|fontname="Noto Sans CJK JP"| s|fontname="BitStream Vera Sans"|fontname="Noto Sans CJK JP"| s|fontname="monospace"|fontname="DejaVu Sans Mono"| ' "$@"
dotconv.sh DOTFILE.dot | convert -density 96 -format dot - converted.png