0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FFmpeg+SRT(その3)

Posted at

思いつきが後日有益になるかもしれないので続けた

その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パケット)。

LogTest2.png

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で取得したデータを下記。

狭帯域SRT.PNG

実際のデータを転送しているDATAが少ないことがわかる。Controlパケットのみでフィルターする。

狭帯域Cntr多し - コピー.PNG

Controlパケットが3分の2(67.4%)も占めている。

おまけ(最後に)

ChatGPTは有益であるが、不適切な情報を回答してくることもあるようだ。そのため、その1-3で、相当数のトライ&エラーを実施。ただし、無償版ChatGPT利用だからかもしれない。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?