WebRTC de m2ts 調査メモ
そこそこに厳しい。
流れ
作ってみよう
前提
サーバーから m2ts をリアルタイムで送信する
送る m2ts は以下の様な感じ
映像:Stream #0:0[0x1011]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn
音声:Stream #0:1[0x1100]: Audio: aac (LC) ([6][0][0][0] / 0x0006), 48000 Hz, stereo, fltp, 255 kb/s
映像の再エンコードはしない
GPU とか詰んでいないサーバーで動かすので、しないというより無理
普通に DataChannel で m2ts を転送する。一番最初に考えついてまあこれでうまくいくだろうと思っていた方法。甘かった。
厳しいと思っていたのは全て WebArena Indigo の UDP の異常な制約の問題で、DataChannel 自体に問題はありませんでした。下記取り消し線部分。 DataChannel は現状殆どの実装において 65535 bytes 単位でしかデータを送信できない
毎秒 1MB 超えのペイロードを送ろうとすると…計算上は15回/秒ぐらい?
自前の実装だと 100 回/秒を超すんだけど何か実装も悪い気がしてきた
頻度が高くて小さいデータというのは、色んな面に置いて苦しい
送信側の負荷が結構大きい
M1 Pro の MBP で 1 受信者あたり 10% とか
帯域を圧迫する?
これはよくわからないのだけど、しばらく送信していると対象ホストとのネットワークが不通になってしまう
WebRTC は割りと他の通信に影響することがある(確証があるわけでなく実体験より)のでそれかなと思っている
例えば:手元で WebRTC のテストをしていると Discord の画面共有がおかしくなる
ネットワークの相性が結構良くないと送信が間に合わない
よくなかったので 1x 出ず実用不可
m2ts をデコードして中身を送信する
元映像ソースの性質によっては、無理だと思っていたけど出来ることがわかった。
えっ WebRTC で DataChannel を!?
できらぁ!
らしいので試していた
入力の要件は以下のような感じ
映像:h264
WebRTC で受け付けられるフォーマットなら何でも良い
音声:opus
WebRTC が aac に対応してないため
ここの再エンコードは軽量なので許容する
流れ
トラックを 2 つ作って、フレームごとに RTP パケットにして送る
これでほぼうまく動いた、ほぼというのは、一部のファイル(手元のほとんどのファイル)で正しく動かない
これが「元映像ソースの性質によっては」
正しく動くファイルは「B フレームが使われていないファイル」
WebRTC は B フレームをサポートしていないので!
bf=0にして再エンコしろ、まあそうですね…
送信したい映像はほとんど B フレームを使っているので、この方法だと映像がかなり狂う
ガッチャガチャになる
https://gyazo.com/04929fc544d391b52ff4bd9321583f6f
音などは正常なので、映像が異常にガタつくことを許容できる目的なら大丈夫かもしれない
サーバーから送らせると音もおかしくなってる雰囲気あります!フレームに合わせようとするから??
ローカル送出受信だと問題ない…
ほとんど P フレームで賄えないかと思い、無理やり B フレームだけ引っこ抜く実験もしてみたが、まあうまくいくはずがなかった
ここらへんの知識が全然ないのでやり方が悪いのかも
とりあえず WebRTC Encoded Transform の最もカスな用途として、B フレームガチャガチャ映像対策のキーフレーム以外全部無視というのをやっています
概要がわかればよい用途のため
h264 の形をしたパケットの中に m2ts を紛れ込ませて Encoded Transform で引っこ抜く & 素直に MSE できればする
できていない!
ここらへんの記事によればできそうなことが書いてあるんだけど…そもそも RTCEncodedVideoFrame で降ってきてるこのバイナリはなんなの?生フレーム?