Skip to content

Instantly share code, notes, and snippets.

@tzmartin
Last active April 9, 2024 10:13
Show Gist options
  • Save tzmartin/fb1f4a8e95ef5fb79596bd4719671b5d to your computer and use it in GitHub Desktop.
Save tzmartin/fb1f4a8e95ef5fb79596bd4719671b5d to your computer and use it in GitHub Desktop.
m3u8 stream to mp4 using ffmpeg

1. Copy m3u8 link

Alt text

2. Run command

echo "Enter m3u8 link:";read link;echo "Enter output filename:";read filename;ffmpeg -i "$link" -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 $filename.mp4

Alt text

Example final command

ffmpeg -i "http://host/folder/file.m3u8" -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 file.mp4
@savinggrace
Copy link

Tried using VLC and it was being tempermental on me, this worked so much better thank you

VLC interrupts the recording sometimes, but much more simple.

@pvonmoradi
Copy link

@varenc thanks for this break-down. Wouldn't ffplay "$link" essentially do the same thing? (No need to use ffmpeg)

@pengyuwei
Copy link

How do I download m3U8 files that are encrypted using key? Such as:

#EXT-X-KEY:METHOD=AES-128,URI="https://xxxxx.com/somepath/somekey.key",IV=0x00000000000000000000000000000000

@varenc
Copy link

varenc commented Aug 19, 2021

@varenc thanks for this break-down. Wouldn't ffplay "$link" essentially do the same thing? (No need to use ffmpeg)

If you just want play the stream and watch it once, I agree it is! But then you might as well use mpv or VLC to play the stream. I figure people finding this gist want to download the stream and keep the media around for later viewing too.

@jokester
Copy link

jokester commented Oct 2, 2021

Thanks for the snippet, saved my day 👍

ffmpeg newbie here but, can I ask why -crf 50 was used when the encoder is copy ? Will it make a difference?

@varenc
Copy link

varenc commented Oct 2, 2021

ffmpeg newbie here but, can I ask why -crf 50 was used when the encoder is copy ? Will it make a difference?

You're right, it does nothing! Since there's no encoding going on and the stream is just being copied, -crf 50 has no effect. I broke this down more in my comment above.

This command is all you need: ffmpeg -i "http://host/folder/file.m3u8" -c copy file.mp4

@DaveFlashNL
Copy link

This command is all you need: ffmpeg -i "http://host/folder/file.m3u8" -c copy file.mp4

yes, but it only picked up the English audio in my stream just now, no subtitles, no other languages. how to fix that?

@Martyn575
Copy link

Martyn575 commented Aug 6, 2022

Does not work don't waste your time with garbage.

Fills my screen with millions of lines of garbage text. No closer to having anything usable.

Still trying to find alternate ways to convert this. Between censorship and youtube doing this, can't see any reason at all to use google products ever again.

@ibillabong
Copy link

This worked for me - when ripping from other site - however I had the following error:
Protocol 'http' not on whitelist 'file,crypto,data'!

By adding "-protocol_whitelist file,http,https,tcp,tls" before "-i" fixed this error. So:
ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -i [input] [flags] [output]

@ilyazub
Copy link

ilyazub commented Sep 9, 2022

This command is all you need: ffmpeg -i "http://host/folder/file.m3u8" -c copy file.mp4

Thanks! How to speed up the download (like, download concurrently?)

@varenc
Copy link

varenc commented Sep 9, 2022

This command is all you need: ffmpeg -i "http://host/folder/file.m3u8" -c copy file.mp4

Thanks! How to speed up the download (like, download concurrently?)

@ilyazub
For concurrently downloading you can't just use ffmpeg by itself. However, here are 2 things you can try:

Option 1

Use yt-dlp** or youtube-dl with aria2c as an external downloader. This just makes yt-dlp leverage aria2c for media downloading so you get concurrency.

$ yt-dlp --external-downloader aria2c --external-downloader-args '-c -j 8 -x 8 -s 8 -k 2M' "https://host/folder/file.m3u8"

Note the args I've set for aria2c in the above example. These tell aria2c to continue partial downloads, to use 8 parallel download requests, and to limit each request to 2MB each (-k 2M). Feel free to try tuning these parameters. For most situations limiting each download to 2M will slow things down but sometimes media hosts (dailymotion) apply traffic policies that allow the first part of a download stream to go very fast, but then they start rate limiting the download as it continues. By restarting each request after 2M you can sometimes subvert these limits.

Option 2

Use yt-dlp or youtube-dl to extract the relevant URLs and then use aria2c manually for concurrent downloading. Like this:

$  yt-dlp -g "https://host/folder/file.m3u8"  # the -g flag tells youtube-dl to just return the media url[s]
...
https://media.clip.host/..../media.mp4
$ aria2c "https://media.clip.host/..../media.mp4"

Warning: often a root .m3u8 references other .m3u8 files which then reference the media so you might need to follow the tree of references a few levels deep.

**These days I recommend yt-dlp over youtube-dl. It's just a fork but it seems more regularly updated and in general succeeds more often for me.

@tronghieu60s
Copy link

I'm having a problem trying to decode when the player is using the fake img link, I see the video file has a ?PNG at the beginning of the content, anyone have a way to fix this?

File .m3u8

#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:7
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:6
https://s5.bestchill.workers.dev/sg/MjAyMjA5MjJfMjgg/MDAxNjYzODM5MTIyMjQz.2NlYD5uKQINWCu4tSseNg5wAEMPSpLqy1uPC7PsqwrAg.rPpnj1itZm2hbQWcxJ3uGzDHhzhWQDeirLrwZ4zrcHkg/index.html
#EXTINF:6
https://s1.bestchill.workers.dev/sg/MjAyMjA5MjJfMTM0/MDAxNjYzODM5MTIyMjA4.09L5NGYqCUWXn0Ff__jugCt3hzYxnovpjrvg0fG4SVIg.CXsKbhRODTttikxbAd0RQiQnvvWDAKtU_cNhlsieookg/index.html
#EXTINF:5.6
https://s3.bestchill.workers.dev/sg/MjAyMjA5MjJfNDgg/MDAxNjYzODM5MTM0OTc1.o-awTLVDuR2c1fV7bdavYODnsl7M0p5PCP05Q07fjiQg.8LIfxzp--TCKU3buOCkznGCGHMvnyabAbjvyH2pN0MEg/index.html
#EXTINF:6
...

File HLS index.html

�PNG � IHDR����ؿů pHYs�������� cHRMz%������u0�`:��o�_�F�IDATx�b,�����������
...

This is 2 file example:

https://github.com/tronghieu60s/tronghieu60s.github.io/blob/master/index.m3u8
https://github.com/tronghieu60s/tronghieu60s.github.io/blob/master/index.html

@ilyazub
Copy link

ilyazub commented Oct 3, 2022

@varenc Thank you the solution with yt-dlp and aria2c!

@luxin88
Copy link

luxin88 commented Jan 25, 2023

if the url in m3u8 should with some header(like cookie), how to run it?

sometime some url thow 403, if I ue curl with header, it run successful

maybe we can add a Reverse Proxy between ffmpeg and site

@raleighlittles
Copy link

If you run this exact command on newer FFMPEG versions you'll probably get an error about something not being on the whitelist: protocol https not on whitelist

Modify the command to use this instead

$ ffmpeg -protocol_whitelist file,https,tcp,tls -i master.m3u8 -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 video.mp4 

Tested with FFMPEG versions 5.0 and newer

@ArgX11
Copy link

ArgX11 commented Sep 6, 2023

Thanks! How to speed up the download (like, download concurrently?)

Use N_m3u8DL-RE with -mt argument.

@sanjukhunt
Copy link

Tried using VLC and it was being tempermental on me, this worked so much better thank you

can you please share more details how we can convert using VLC Kit?

@kolbdog3333
Copy link

Works great also i noticed if you copy a 1280x720 youtube video url from download helper and use this method it downloads the 1920x1080 video instead it downloads a higher qualtiy video then the original. It works perfectly thank you.

@garretttaco
Copy link

This works perfectly, thanks for sharing!

@geraldotech
Copy link

nice work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment