web-dev-qa-db-ja.com

FFMPEGを使用して、ビデオファイルをRTMPサーバーに連続的にストリーミングする

ffmpegはRTMPストリーミングを入力または出力として処理し、正常に機能しています。

私はいくつかのビデオ(pythonスクリプトによって管理される動的なプレイリスト)をRTMPサーバーにストリーミングしたい、そして私は現在非常に簡単なことをしている:FFMPEGでビデオを一つずつストリーミングするただし、RTMPサーバーでは、ビデオが終了するたびに接続が切断され、次のビデオの開始時にストリームの準備が整います。

接続を継続的に中断せずにこれらのビデオをストリーミングしたい場合、ストリームを正しく表示できます。

このコマンドを使用して、ビデオを1つずつサーバーにストリーミングします

ffmpeg -re -y -i myvideo.mp4 -vcodec libx264 -b:v 600k -r 25 -s 640x360 \
-filter:v yadif -ab 64k -ac 1 -ar 44100 -f flv \
"rtmp://mystreamingserver/app/streamName"

私は何日もインターネットでいくつかの回避策を探しましたが、ffmpegの入力として名前付きパイプを使用することについて話している人がいるのを見つけました。それを試してみましたが、ffmpegは、新しいビデオが来たときにRTMPストリームを閉じるだけでなく、それ自体も閉じます。

これを行う方法はありますか? (ffmpegを含む動画の動的なプレイリストを、接続が切れることなくRTMPサーバーにストリーミングします

22
kketch

更新(受け入れられた回答を削除できないため):適切な解決策は、concatのようなカスタムデマルチプレクサを実装することです。現在、他のクリーンな方法はありません。手を汚してコーディングする必要があります!

以下はいハックです。これは非常に悪い方法です。ただやらないでください!

ソリューションはconcat demuxerを使用し、すべてのソースメディアファイルが同じコーデックを使用することを想定しています。この例はMPEG-TSに基づいていますが、RTMPでも同じことができます。

  1. 次の形式で、ダイナミックプレイリストのエントリポイントの膨大なリストを保持するプレイリストファイルを作成します。

    file 'item_1.ts' file 'item_2.ts' file 'item_3.ts' [...] file 'item_[ENOUGH_FOR_A_LIFETIME].ts'

    これらのファイルは単なるプレースホルダーです。

  2. 現在のプレイリストインデックスを追跡し、current_index + 1のオンザフライでシンボリックリンクを作成するスクリプトを作成します

    ln -s /path/to/what/to/play/next.ts item_1.ts

    ln -s /path/to/what/to/play/next.ts item_2.ts

    ln -s /path/to/what/to/play/next.ts item_3.ts

    [...]

  3. ffmpeg -f concat -i playlist.txt -c copy output -f mpegts udp://<ip>:<port>の再生を開始します

  4. 怒っているシステム管理者に追われて呼ばれた名前を取得する

7
aergistal

2つのプレイリストファイルを作成し、各ファイルの最後に別のファイルへのリンクを指定する必要があります。

list_1.txt

ffconcat version 1.0
file 'item_1.mp4'
file 'list_2.txt'

list_2.txt

ffconcat version 1.0
file 'item_2.mp4'
file 'list_1.txt'

あとは、次のプレイリストファイルの内容を動的に変更するだけです。

1
bnku

ループをバッファにパイプし、このバッファからストリーミングインスタンスにパイプすることができます。

シェルでは次のようになります。

#!/bin/bash

for i in *.mp4; do
       ffmpeg -hide_banner -nostats -i "$i" -c:v mpeg2video [proper settings] -f mpegts -
done | mbuffer -q -c -m 20000k | ffmpeg -hide_banner -nostats -re -fflags +igndts -thread_queue_size 512 -i pipe:0 -fflags +genpts [proper codec setting] -f flv rtmp://127.0.0.1/live/stream

もちろん、あらゆる種類のループを使用でき、プレイリストをループすることもできます。

  • 私はmpegがもう少し安定していることを理解し、入力ストリームのx264
  • 理由はわかりませんが、MPEG圧縮の最小2スレッドがより適切に機能します
  • 入力圧縮は出力フレームレートよりも高速である必要があるため、新しい入力が十分に高速になります。
  • タイムスタンプが継続しないため、それらをスキップして、出力に新しいものを生成する必要があります
  • バッファサイズは、ループが新しいクリップを取得するのに十分な時間を確保するのに十分な大きさである必要があります。

私はpythonベースのソリューションに取り組んでいますが、まだ完了していませんが、テストストリームが数日間実行されるいくつかの警告を除きます:

ffplayout

これは、xmlプレイリスト形式を使用します。また、プレイリストは動的であるため、常に現在のプレイリストを編集したり、トラックを変更したり、新しいトラックを追加したりできます。

1
jb_alvarado