この記事でわかること

  • UDPストリーミングの特徴:コネクションレスで低遅延、ただしパケットロス回復は無い
  • ユニキャスト(1対1)の送受信コマンド
  • マルチキャスト(1送信→複数受信)の配信方法
  • 主要パラメータ:pkt_sizefifo_sizeoverrun_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=1316MPEG-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 6060フレームごとにキーフレーム(受信開始点を増やす)
-c:a aac -b:a 128k音声をAAC 128kbpsにエンコード
-f mpegtsMPEG-TSコンテナで送出

-maxrate-bufsizeでビットレートの山を抑えることで、UDP伝送で帯域を超過してパケットロスを誘発するのを防ぎます。-g 60で定期的にキーフレームを入れておくと、受信側が途中から接続しても短時間で映像が出始めます。


RTMP・SRTとの使い分け

ライブ伝送のプロトコルは用途で選び分けます。それぞれの特性を整理します。

プロトコルトランスポートロス回復主な用途
UDPUDP無しLAN内の超低遅延伝送・モニタリング
SRTUDP + 再送有り(ARQ)不安定な回線・インターネット越しの低遅延配信
RTMPTCP有り(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 チートシート

関連記事


テスト環境: 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が必須です。