この記事でわかること
- UDPストリーミングの特徴:コネクションレスで低遅延、ただしパケットロス回復は無い
- ユニキャスト(1対1)の送受信コマンド
- マルチキャスト(1送信→複数受信)の配信方法
- 主要パラメータ:
pkt_size・fifo_size・overrun_nonfatalの意味と使いどころ - 再エンコードしながら送出する本番向けコマンド
- RTMP・SRTとの使い分けの判断基準
テスト済みバージョン: FFmpeg 6.1(検証スクリプトで実 FFmpeg 実行確認)
対象 OS: Windows / macOS / Linux
UDPストリーミングとは
UDP(User Datagram Protocol)は、TCPと異なりコネクションレスで動作するトランスポートプロトコルです。ハンドシェイクや再送制御を行わないため、オーバーヘッドが小さく、低遅延で映像を伝送できます。FFmpegはudp://プロトコルでこのUDP伝送に直接対応しています。
ただし、UDPには重要な前提があります。パケットロスが発生しても回復する仕組みが無いという点です。SRTやTCPベースのRTMPと違い、途中で失われたパケットは再送されません。つまり、ネットワークがパケットを落とせば、そのぶん映像は乱れます。
この性質から、UDPストリーミングは次のような用途に最適です。
| 向いている用途 | 向いていない用途 |
|---|---|
| 管理されたLAN内の伝送 | インターネット越しの配信 |
| スイッチ直結など低ロス環境 | 無線・モバイルなどロスが多い経路 |
| 超低遅延が必要な現場(中継・モニタリング) | ロス耐性・信頼性が必須の配信 |
UDPで運ぶコンテナには、ストリーミングに適した**MPEG-TS(MPEG Transport Stream)**を使います。FFmpegでは-f mpegtsで指定します。MPEG-TSは188バイト固定長のパケットで構成されており、途中から受信を開始できる(自己同期できる)ため、ライブ伝送に向いています。
ユニキャスト送受信
ユニキャストは、1つの送信元から1つの受信先へ届ける1対1の伝送です。受信側のIPアドレスとポートを指定します。
送信(再エンコードなし)
入力がすでにストリーミングに適したコーデック(H.264 + AAC)であれば、再エンコードせずそのまま流すのが最も軽量です。
ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://192.168.1.50:1234"
-re:ファイルをネイティブのフレームレートで読み込む指定です。これが無いとFFmpegは可能な限り高速にファイルを送出してしまい、ライブ伝送として成立しません。リアルタイム配信では必須です。-c copy:再エンコードせずストリームをコピーします。CPU負荷が低く、画質劣化もありません。-f mpegts:UDPで運ぶコンテナをMPEG-TSに指定します。udp://192.168.1.50:1234:送信先(受信機)のIPとポートです。
受信して保存
受信側では、自分のすべてのインターフェースで待ち受ける0.0.0.0を指定し、ファイルに保存できます。
ffmpeg -i "udp://0.0.0.0:1234" -c copy received.mp4
0.0.0.0は「このマシンの全インターフェースで指定ポートを受信する」という意味です。-c copyで再エンコードせずそのままreceived.mp4に書き出します。
受信して再生(ffplay)
保存ではなくモニタリング目的なら、ffplayでそのまま再生確認できます。
ffplay "udp://0.0.0.0:1234"
送信側と受信側を別々のマシン(または同一マシンの別ターミナル)で起動すれば、LAN越しの低遅延伝送をすぐに試せます。
マルチキャスト配信
ユニキャストは1対1ですが、マルチキャストを使えば1回の送信で複数の受信者に同時配信できます。送信側はネットワークに1本のストリームを流すだけで、対応したスイッチ・ルータが必要な受信者にだけ複製して届けます。受信者が増えても送信側の帯域は増えません。
マルチキャストには専用のIPアドレス範囲を使います。代表的なのは239.0.0.0/8(ローカルスコープ、組織内マルチキャスト用に予約された範囲)です。グローバルなアドレスと衝突しないため、LAN内の配信に安全に使えます。
マルチキャスト送信
ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://239.0.0.1:1234?pkt_size=1316"
宛先がマルチキャストアドレス(239.0.0.1)になっている点がユニキャストとの違いです。ここではpkt_size=1316を指定しています(後述)。ポート番号(1234)は用途に合わせて読み替えてかまいません。
マルチキャスト受信
受信側は、配信されているマルチキャストアドレスをそのまま指定します。
ffplay "udp://239.0.0.1:1234"
同じアドレスを指定した受信者は、複数台あっても全員が同じストリームを受け取れます。デジタルサイネージや教室の一斉配信のように「同じ映像を多数の端末に届けたい」ケースで威力を発揮します。
なお、マルチキャストはルータやスイッチ側の設定(IGMP対応など)に依存します。家庭用ルータや一部のスイッチではマルチキャストがブロック・フィルタされることがあるため、配信が届かない場合はネットワーク機器の設定を確認してください。
主要パラメータ(pkt_size・fifo_size・overrun_nonfatal)
UDPプロトコルにはURLのクエリ文字列(?key=value&...)で渡すパラメータがあります。安定した伝送のために押さえておきたいものを整理します。
pkt_size
pkt_sizeは、UDPで送出する1パケットあたりのバイト数です。MPEG-TSは188バイト固定長なので、その整数倍にするのが定石です。
188 バイト × 7 = 1316 バイト
pkt_size=1316はMPEG-TSパケット7個ちょうどに相当し、なおかつ一般的なイーサネットのMTU(1500バイト)に収まるため、IPフラグメンテーション(断片化)を避けられます。UDPでMPEG-TSを流すときの推奨値です。
ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://192.168.1.50:1234?pkt_size=1316"
fifo_size と overrun_nonfatal
受信側は、到着したパケットを内部のFIFOバッファ(リングバッファ)に一時的に溜めてから処理します。送出レートが高い、または受信処理が一時的に追いつかない場面では、このバッファがあふれることがあります。
fifo_size:受信FIFOバッファのサイズを大きくして、瞬間的な流入の山を吸収します。単位はパケット数で、デフォルトより大きくすることで途切れを抑えられます。overrun_nonfatal=1:バッファがあふれた(オーバーラン)際に、エラーで停止せず処理を継続します。多少のロスを許容してでも受信を止めたくない場合に有効です。
両方を組み合わせた受信コマンドが次です。
ffmpeg -i "udp://0.0.0.0:1234?overrun_nonfatal=1&fifo_size=1000000" -c copy received.mp4
fifo_size=1000000で大きめのバッファを確保し、overrun_nonfatal=1であふれても落ちないようにしています。「Circular buffer overrun」という警告が出る環境では、この2つで安定化を図ります。
再エンコードして送出する
入力のコーデックやビットレートがそのままでは伝送に適さない場合(巨大すぎる、コーデックが非対応など)は、送出時に再エンコードします。ライブ伝送向けに、低遅延・一定ビットレートを意識した設定が次です。
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2000k -maxrate 2000k -bufsize 4000k -pix_fmt yuv420p -g 60 -c:a aac -b:a 128k -f mpegts "udp://192.168.1.50:1234?pkt_size=1316"
各オプションの意図は次のとおりです。
| オプション | 意味 |
|---|---|
-c:v libx264 | 映像をH.264にエンコード |
-preset veryfast | エンコード速度優先(ライブで遅延を抑える) |
-b:v 2000k | 映像ビットレート目標 2Mbps |
-maxrate 2000k / -bufsize 4000k | レート上限とVBVバッファで一定帯域に収める |
-pix_fmt yuv420p | 互換性の高いピクセルフォーマット |
-g 60 | 60フレームごとにキーフレーム(受信開始点を増やす) |
-c:a aac -b:a 128k | 音声をAAC 128kbpsにエンコード |
-f mpegts | MPEG-TSコンテナで送出 |
-maxrateと-bufsizeでビットレートの山を抑えることで、UDP伝送で帯域を超過してパケットロスを誘発するのを防ぎます。-g 60で定期的にキーフレームを入れておくと、受信側が途中から接続しても短時間で映像が出始めます。
RTMP・SRTとの使い分け
ライブ伝送のプロトコルは用途で選び分けます。それぞれの特性を整理します。
| プロトコル | トランスポート | ロス回復 | 主な用途 |
|---|---|---|---|
| UDP | UDP | 無し | LAN内の超低遅延伝送・モニタリング |
| SRT | UDP + 再送 | 有り(ARQ) | 不安定な回線・インターネット越しの低遅延配信 |
| RTMP | TCP | 有り(TCP) | 配信プラットフォームへの入稿(YouTube/Twitch等) |
判断の目安は次のとおりです。
- UDP:閉じた・管理されたLANで、とにかく遅延を最小にしたいとき。スイッチ直結のような低ロス環境が前提です。インターネット越えやロスの多い経路には不向きです。
- SRT:インターネット越しでも低遅延を保ちたいとき。UDPベースながら独自の再送(ARQ)でパケットロスを回復するため、UDPの弱点を補えます。
- RTMP:配信プラットフォームへ映像を送り込むとき。多くのサービスが受け口として対応しており、TCPベースで信頼性があります。
「LAN内で1ms単位の遅延も惜しい」ならUDP、「ネット越しで安定させたい」ならSRT、「配信サービスに入稿したい」ならRTMP、と覚えておくと迷いません。
よくあるエラーと対処
受信できない
最も多いのがこのケースです。次を順に確認します。
- ポート番号の不一致:送信側と受信側で同じポート(例:
1234)を指定しているか。 - ファイアウォール:受信側マシンのファイアウォールがUDPの該当ポートをブロックしていないか。WindowsやLinux(ufw/firewalld)で受信ポートを開放します。
- マルチキャストのブロック:マルチキャスト配信の場合、ルータ・スイッチがマルチキャスト(IGMP)を転送しない設定だと届きません。同一スイッチ配下で試す、ネットワーク機器のマルチキャスト設定を確認する、などで切り分けます。
映像が乱れる
ブロックノイズや音飛びが出る場合、パケットロスが発生している可能性が高いです。UDPはロスを回復できないため、対処は根本のネットワーク側になります。
- 帯域を確保する(
-maxrateを下げてビットレートを抑える、有線にする)。 - 経路上の輻輳を解消する。
- どうしてもロスが避けられない経路なら、ロス回復のあるSRTへの移行を検討します。
Circular buffer overrun
受信側のバッファがあふれていることを示す警告です。受信処理が流入に追いつかないときに出ます。
ffmpeg -i "udp://0.0.0.0:1234?overrun_nonfatal=1&fifo_size=1000000" -c copy received.mp4
fifo_sizeを大きくしてバッファ容量を増やし、overrun_nonfatal=1であふれても停止しないようにします。
遅延が大きい
バッファを増やしすぎると、その分だけ遅延が増えます。安定性と引き換えになるため、fifo_sizeは「途切れない範囲で最小限」に調整します。低遅延を最優先するなら、再エンコード時の-presetを速めにし、過大なバッファ設定を避けます。
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
テスト環境: ffmpeg 6.1.1 / Ubuntu 24.04(検証スクリプトで実行確認)
一次ソース: ffmpeg.org/ffmpeg-protocols.html#udp / trac.ffmpeg.org/wiki/StreamingGuide
よくある質問
UDPとSRTはどちらを使うべき?
経路が管理されたLANで低ロスなら、軽量で超低遅延なUDPが第一候補です。インターネット越しや無線などロスが避けられない経路では、ロス回復(ARQ)のあるSRTが適しています。UDPは落ちたパケットを回復できないため、信頼性が必要な場面では不利です。
pkt_size はなぜ 1316 なのか?
MPEG-TSパケットは188バイト固定長で、その7個ぶん(188×7=1316)がちょうどイーサネットのMTU(1500バイト)に収まり、IPの断片化を避けられるからです。UDPでMPEG-TSを流すときの定番値です。
マルチキャストアドレスはどの範囲を使えばいい?
LAN内のローカル用途なら239.0.0.0/8(ローカルスコープ)が安全です。グローバルアドレスと衝突せず、組織内マルチキャスト用に予約されています。受信側は送信と同じアドレス・ポートを指定すれば、複数台が同時に同じストリームを受け取れます。
-re を付け忘れるとどうなる?
FFmpegがファイルを可能な限り高速で送出してしまい、受信側がリアルタイムに処理しきれず破綻します。ファイルをライブのように流すときは、ネイティブレートで読む-reが必須です。