ffmpegでRTPで映像と音声をストリーミングしてみた。実験なのでlocalhost上で送信と受信を行う。
使用したffmpeg はMac用の4.1
うまくいった方法
SDPファイルの生成
ffmpeg -re -i input.mp4 \
-c:v copy -an -f rtp rtp://localhost:30002 \
-c:a copy -vn -f rtp rtp://localhost:30004 \
-sdp_file out2.sdp
起動したらすぐに^Cで止めてOK。
生成できたSDPファイルは以下の通り。
SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=Big Buck Bunny
t=0 0
a=tool:libavformat 58.20.100
m=video 30002 RTP/AVP 96
c=IN IP6 ::1
b=AS:1495
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=J0LgHqkQFAX/LgDUGAQa23oA9ID1XvfAQA==,KN4JyA==; profile-level-id=42E01E
m=audio 30004 RTP/AVP 97
c=IN IP6 ::1
b=AS:127
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1210
受信側
ffplay -protocol_whitelist "file,rtp,udp" out2.sdp
送信側
ffmpeg -re -i input.mp4 \
-c:v copy -an -f rtp rtp://localhost:30002 \
-c:a copy -vn -f rtp rtp://localhost:30004
受信側を先に起動してから、送信側を実行する。
失敗の記録
最初に試したのはこれ。
ffmpeg -re -i input.mp4 \
-c:v copy -c:a copy -f rtp rtp://localhost:30002 \
-sdp_file out.sdp
これを実行すると
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : M4V
minor_version : 1
compatible_brands: M4V M4A mp42isom
creation_time : 2008-06-03T05:23:28.000000Z
copyright : © 2008 Blender Foundation | www.bigbuckbunny.org
title : Big Buck Bunny
artist : Peach Open Movie Team
composer : Sacha Goedegebure / Ton Roosendaal
date : 2008
Duration: 00:09:56.46, start: 0.000000, bitrate: 1626 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
creation_time : 2008-06-03T05:23:28.000000Z
handler_name : Apple Sound Media Handler
Stream #0:1(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709), 640x359, 1495 kb/s, 24 fps, 24 tbr, 2400 tbn, 4800 tbc (default)
Metadata:
creation_time : 2008-06-03T05:23:28.000000Z
handler_name : Apple Video Media Handler
[rtp @ 0x7feb2d82d800] Only one stream supported in the RTP muxer
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
Last message repeated 1 times
Only one stream supported in the RTP muxer
というエラー。
映像か音声のどちらか片方だけにすると、このエラーは起こらない。
RTPとしては映像と音声を一つのポートで送ることができるが、ffmpegではそれをサポートしていない様子。
映像と音声をそれぞれ別々のポートで送るようにしてみた。
ffmpeg -re -i input.mp4 \
-c:v copy -an -f rtp rtp://localhost:30002 \
-c:a copy -vn -f rtp rtp://localhost:30003 \
-sdp_file out2.sdp
これでSDPファイルは生成できた。
しかし、やってみると受信側で以下のエラーが発生する。
ffplay -protocol_whitelist "file,rtp,udp" out2.sdp
[udp @ 0x7f81d2614300] bind failed: Address already in use
out2.sdp: Invalid data found when processing input
ffmpegのドキュメントを見直すと
https://ffmpeg.org/ffmpeg-protocols.html#toc-rtp
If rtcpport is not set the RTCP port will be set to the RTP port value plus 1.
rtcp のポートとしてRTP +1 のポートが使用される。
なので、映像と音声の2つのRTPポートは連続した値でなくて、一つ離す必要がある。
今回の場合は、30002と30003でなくて、30002と30004 を指定する。
この変更をして、うまくいったものが冒頭のもの。