思いつきが後日有益になるかもしれないので続けた
「その1」や「その2」を実施したときに、+αで思いついたことをここで記載。ChatGPTにかなり聞きながらトライ。
同時に再生とファイル保存
動画を再生しながらファイル保存する、、、というもの。送信側は下記コマンドを実行。
ffmpeg -re -i ファイル -f mpegts srt://192.168.10.110:8888
受信側での単なる保存
まずは単なる保存だけ実施。
ffmpeg -i "srt://192.168.10.110:8888?mode=listener" -c copy -f mpegts 保存ファイル
3回実施し、保存されたファイルは下記。
-rw-rw-r-- 1 xxx yyy 6403656 4月 8 12:46 out1.ts
-rw-rw-r-- 1 xxx yyy 6413808 4月 8 12:47 out2.ts
-rw-rw-r-- 1 xxx yyy 6473592 4月 8 12:48 out3.ts
毎回同じサイズとならない。転送されたファイルの最初と最後が正しく受信できていない可能性が高いと推測。これを前提に次に進む。
Windows Powershellでの受信(実現できず)
単なるNG記録である。下記のいずれもダメであった(同時再生&ファイル保存できず)。
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -map 0:v -map 0:a -c:v copy -c:a copy -f tee "[f=mp4]保存ファイル|[f=nut]pipe:" | ffplay -
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -map 0:v -c:v copy -f tee "[f=mp4]保存ファイル|[f=nut]pipe:" | ffplay -
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -map 0:v -map 0:a? -c:v libx264 -preset ultrafast -c:a aac -b:a 128k -f tee "[f=mp4:movflags=faststart]保存ファイル|[f=nut]pipe:" | ffplay -
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -map 0:v -map 0:a? -c:v libx264 -preset ultrafast -c:a aac -b:a 128k -f tee "[f=mp4:movflags=faststart]保存ファイル|[f=nut]pipe:" | ffplay -f nut -
ffmpeg -fflags nobuffer -reorder_queue_size 100 -i "srt://192.168.56.1:8888?mode=listener&latency=500000" -map 0:v -map 0:a? -c:v libx264 -preset ultrafast -c:a aac -b:a 128k -f tee "[f=mp4:movflags=frag_keyframe+empty_moov]保存ファイル|[f=nut]pipe:" | ffplay -fflags nobuffer -probesize 100M -analyzeduration 100M -f nut -
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener&latency=200000" -map 0:v -map 0:a? -c:v libx264 -preset ultrafast -c:a aac -b:a 128k -f tee "[f=mp4:movflags=frag_keyframe+empty_moov]保存ファイル|[f=nut]pipe:" | ffplay -fflags nobuffer -probesize 100M -analyzeduration 100M -f nut -
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener&latency=200000" -map 0:v -map 0:a? -c:v libx264 -preset ultrafast -c:a aac -b:a 128k -f tee "[f=mp4:movflags=frag_keyframe+empty_moov]保存ファイル|[f=mpegts]pipe:" | ffplay -fflags nobuffer -probesize 100M -analyzeduration 100M -f mpegts -
Linux(Ubuntu)での受信
WindowsでNGとなったため、Ubuntuでトライ、ある程度は動作。
その1
teeコマンドとパイプ”|”とを使うもの。
ffmpeg -i "srt://192.168.10.110:8888?mode=listener" -map 0:v -c copy -flush_packets 1 -f tee "[f=mpegts]保存ファイル|[f=mpegts]pipe:" | ffplay -autoexit -
上記にて、同時に、再生&ファイル保存ができたが、保存されたファイルサイズが、単なるファイル保存と比べて、小さいものとなった。下記は3回実施したときの保存ファイル。
-rw-rw-r-- 1 xxx yyy 4589080 4月 8 12:56 out11.ts
-rw-rw-r-- 1 xxx yyy 4878036 4月 8 12:58 out12.ts
-rw-rw-r-- 1 xxx yyy 4878036 4月 8 13:00 out13.ts
単なるファイル保存では、最大6473592バイト。かなり小さい。
その2
socatで仮想ポートを利用する方法。まずは、下記をバックグランドで実行。
socat -u PIPE udp-sendto:127.0.0.1:12345,so-rcvbuf=10485760 &
ffmpegで転送ファイルを受信および仮想ポートに送信。
ffmpeg -i "srt://192.168.10.110:8888?mode=listener" -map 0:v -c copy -f mpegts pipe:1 | tee >(socat -u - udp-sendto:127.0.0.1:12345) > 保存ファイル
仮想ポートから再生。
ffplay udp://127.0.0.1:12345
下記は3回実施したときの保存ファイル。
-rw-rw-r-- 1 xxx yyy 6400272 4月 8 13:15 out21.ts
-rw-rw-r-- 1 xxx yyy 6403656 4月 8 13:19 out22.ts
-rw-rw-r-- 1 xxx yyy 6396888 4月 8 13:22 out23.ts
単なるファイル保存では、最大6473592バイト。やはりまったく同じにならない。このあたりが限界かもしれない。
ログ関連
受信側の転送速度のログを取りたく実施(同時にWiresharkでキャプチャ)。まず、送信側で下記を実施。
ffmpeg -re -i 転送ファイル -f mpegts srt://192.168.56.1:8888
その1
受信側Windows Powershellにて、下記を実施。表示される内容を、コマンドteeにてファイル化(下記では”log.txt”)するもの。
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -c copy -f mpegts 保存ファイル 2>&1 | tee log.txt
なお、上記コマンド実行時、下記エラーが出るが、ログ化される(保存ファイルもOK)。
ffmpeg : ffmpeg version N-118468-g19a2d26177-20250213 Copyright (c) 2000-2025 the FFmpeg developers
発生場所 行:1 文字:1
+ ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -c ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (ffmpeg version ...mpeg developers:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
その2
オプション”-report”を使うもの。
ffmpeg -fflags nobuffer -i "srt://192.168.56.1:8888?mode=listener" -c copy -f mpegts 保存ファイル -report
”ffmpeg-202500408-171557.txt”のようなログファイルが作成される。
ログファイル
一部抜粋。
frame= 16 fps=0.0 q=-1.0 size= 57KiB time=00:00:05.61 bitrate= 82.6kbits/s speed=10.9x
frame= 31 fps= 30 q=-1.0 size= 101KiB time=00:00:06.09 bitrate= 135.7kbits/s speed=5.91x
frame= 46 fps= 30 q=-1.0 size= 156KiB time=00:00:06.61 bitrate= 193.4kbits/s speed=4.28x
frame= 62 fps= 30 q=-1.0 size= 211KiB time=00:00:07.14 bitrate= 241.5kbits/s speed=3.47x
frame= 77 fps= 30 q=-1.0 size= 256KiB time=00:00:07.63 bitrate= 274.8kbits/s speed=2.96x
.....
frame= 1113 fps= 30 q=-1.0 size= 3328KiB time=00:00:42.17 bitrate= 646.4kbits/s speed=1.14x
frame= 1129 fps= 30 q=-1.0 size= 3328KiB time=00:00:42.71 bitrate= 638.3kbits/s speed=1.13x
frame= 1144 fps= 30 q=-1.0 size= 3584KiB time=00:00:43.20 bitrate= 679.6kbits/s speed=1.13x
frame= 1160 fps= 30 q=-1.0 size= 3584KiB time=00:00:43.74 bitrate= 671.2kbits/s speed=1.13x
frame= 1175 fps= 30 q=-1.0 size= 3584KiB time=00:00:44.24 bitrate= 663.6kbits/s speed=1.13x
frame= 1191 fps= 30 q=-1.0 size= 3584KiB time=00:00:44.77 bitrate= 655.7kbits/s speed=1.13x
frame= 1206 fps= 30 q=-1.0 size= 3584KiB time=00:00:45.26 bitrate= 648.6kbits/s speed=1.13x
frame= 1222 fps= 30 q=-1.0 size= 3584KiB time=00:00:45.81 bitrate= 640.9kbits/s speed=1.12x
frame= 1237 fps= 30 q=-1.0 size= 3840KiB time=00:00:46.31 bitrate= 679.3kbits/s speed=1.12x
小生のテスト環境では、640-680kbps程度。
Wireshark
この時のWiresharkキャプチャデータをグラフ化したもの(SRTのDATAパケット)。
700-1000kbps程度。ffmpegのデータと乖離があるが、普通に考えると、Wiresharkのデータの方が正確であろう。
狭帯域転送
まず、Linux側で強制的に100kbpsとした。
sudo tc qdisc add dev enp0s3 root netem rate 100kbit
受信側は下記で待つ。
ffplay -fflags nobuffer -autoexit "srt://192.168.56.1:8888?mode=listener"
送信側のコマンドサンプル(Ubuntuにて)は下記。
ffmpeg -f v4l2 -video_size 320x240 -framerate 10 -input_format yuyv422 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -preset veryfast -tune zerolatency -crf 35 -b:v 80k -f mpegts "srt://192.168.56.1:8888?pkt_size=1316&latency=1000000"
100kbpsという帯域を意識したオプションを選択
- -f v4l2:入力フォーマットVideo4Linux2
- -video_size 320x240:解像度320x240
- -framerate 10:フレームレート10fps
- -input_format yuyv422:YUYV4:2:2ピクセルフォーマット
- -i /dev/video0:カメラデバイス
- -pix_fmt yuv420p:YUV4:2:0出力フォーマット
- -c:v libx264:H.264(libx264)ビデオコーデック
- -preset veryfast:圧縮効率大
- -tune zerolatency:遅延を最小化
- -crf 35:圧縮率大(デフォルト:23)
- -b:v 80k:最大ビットレート80kbps(100kbpsを考慮)
- latency=1000000:遅延を1000ms(適度なバッファ)
この条件では、受信側での表示開始に相当の時間(転送開始から少なくとも18秒以上)を要し、開始前のデータはほぼ捨てられていたようだ。ただし、その後の受信側での遅延は1秒程度(”latency=1000000”に依存?)。
この時のWiresharkで取得したデータを下記。
実際のデータを転送しているDATAが少ないことがわかる。Controlパケットのみでフィルターする。
Controlパケットが3分の2(67.4%)も占めている。
おまけ(最後に)
ChatGPTは有益であるが、不適切な情報を回答してくることもあるようだ。そのため、その1-3で、相当数のトライ&エラーを実施。ただし、無償版ChatGPT利用だからかもしれない。


