web-dev-qa-db-ja.com

一度に.m3u8をダウンロードする方法

リモートホストに.m3u8ファイルがあり、チャンク.tsファイル名の固定数が含まれていて、ストリームではありません。

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:9.736,
media_0.ts
#EXTINF:9.96,
media_1.ts
#EXTINF:10.0,
media_2.ts
#EXTINF:10.0,
media_3.ts
#EXTINF:10.0,
media_4.ts
#EXTINF:10.2,
media_5.ts
#EXTINF:10.0,

このコマンドを使用すると:

# ffmpeg -i "http://example.com/chunklist.m3u8" file.mp4

frame=  582 fps=9.4 q=28.0 size=    1536kB time=00:00:23.21 bitrate= 542.1kbits/s dup=2 drop=4 speed=0.375x

できます。しかし、フレームごとのビデオと非常に長い時間が必要です。 (ビデオの再生にはほとんど時間がかかります。)

しかし、すべての.tsファイルのパスがわかっているためです。 ( http://example.com/media_0.tshttp://example.com/media_1.ts 、...)取得する方法が必要ですそれらをすべて同時にマージします。

しかし、どうやって ffmpeg を直接入力しますか?!

編集(解決策を試す):

1つの解決策として、ffmpegを使用してファイルを連結する方法を知っています。

ffmpeg -i "concat:0.ts|1.ts|2.ts|3.ts|4.ts|5.ts" -c copy output.mp4

このffmpegコマンドは素晴らしく、1秒未満で動作します!

次のコマンドを使用して、CURLですべての.tsファイルをダウンロードしてみてください。

curl \
http://example.com/media_0.ts -o 0.ts \
http://example.com/media_1.ts -o 1.ts \
http://example.com/media_2.ts -o 2.ts \
http://example.com/media_3.ts -o 3.ts \
http://example.com/media_4.ts -o 4.ts \
http://example.com/media_5.ts -o 5.ts

しかし、結果を見ることができます:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  687k  100  687k    0     0  75108      0  0:00:09  0:00:09 --:--:-- 74111
100  652k  100  652k    0     0  59404      0  0:00:11  0:00:11 --:--:-- 53400
100  673k  100  673k    0     0  48675      0  0:00:14  0:00:14 --:--:-- 55781
100  657k  100  657k    0     0  63573      0  0:00:10  0:00:10 --:--:-- 62494
100  671k  100  671k    0     0  39019      0  0:00:17  0:00:17 --:--:-- 40863
100  692k  100  692k    0     0  63480      0  0:00:11  0:00:11 --:--:-- 80049

すべてのパーツの合計時間は59秒ですが、合計ダウンロード時間は72秒でした。今回はとても長いです!

申し訳ありませんが、すべてのパーツをダウンロードしてから、それを連結してください。

編集2

別のサーバーで別の.m3u8ファイルを試し、URLを変えます。

一緒にダウンロードして連結する:

ffmpeg -i "concat:\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_0.ts|\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_1.ts|\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_2.ts|\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_3.ts|\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_4.ts|\
http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_5.ts\
" -c copy -y output.ts

input.txt URLsファイルを使用する別のコマンド。

ffmpeg -f "concat" -i "input.txt" -c copy -y output.ts

input.txtファイル:

file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_0.ts'
file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_1.ts'
file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_2.ts'
file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_3.ts'
file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_4.ts'
file 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/media_w442897525_b560000_5.ts'

または、必要に応じてこのコマンドをしばらく実行します。

ffmpeg -f "concat" -safe "0" -protocol_whitelist "file,http,https,tcp,tls" -i "input.txt" -c copy -y output.ts

最後に、そのダウンロード速度が良かったため、サーバーターゲットの帯域幅が制限されている可能性があります。 :-(

6
Nabi K.A.Z.

M3u8プレイリストから複数のビデオファイルを連結する正しい方法は、

ffmpeg -i "http://example.com/chunklist.m3u8" -codec copy file.mp4


  • m3u8プレイリストは、Webまたはローカルディレクトリにあります。
    • プレイリストに関連するファイルパスのリストが含まれています
  • -codec copyエンコードを回避する(時間がかかる)
  • コンテナタイプが重要:
    • *.mp4は問題ありませんが、Webからプレイリストを取得するときに、muxの動作が少し遅いようです
    • *.mkvまたは*.ts自分に最適
10

あなたが試すことができます。

command: ffmpeg -y \ -v warning \ -loglevel debug \ -i "m3u8 url" \ -vcodec copy \ -c copy -f mpegts out.ts

tsをmp4に変換します。

ffmpeg -i out.ts -acodec copy -vcodec copy out.mp4

0
Gatspy

ここにいくつかのpythonそれを行うコードがあります。最初のセグメントのURLとセグメントの数(.m3u8ファイルから)を指定するだけです):

def dumpSegs(initUrl, n, path, append=False):
    """ downlaod and combine the .ts files
    given the first seg's url, the number of segments and
    the destination download path """
    with open(path, 'ab' if append else 'wb') as f:
        for i in range(1, n + 1):
            segurl = initUrl.replace('seg-1-', 'seg-{:d}-'.format(i))
            success = False
            while not success:
                try:
                    seg = requests.get(segurl, headers=HEADERS)
                    success = True
                except:
                    print('retrying...')
            f.write(seg.content)

ここ は同じコードで、もう少しベルとホイッスルがあります

0
sam46