Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
@xinshangshangxin

This comment has been minimized.

Copy link

@xinshangshangxin xinshangshangxin commented May 18, 2018

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

@amirasaran

This comment has been minimized.

Copy link

@amirasaran amirasaran commented May 25, 2018

Thanks

@gaojingwen945

This comment has been minimized.

Copy link

@gaojingwen945 gaojingwen945 commented Aug 13, 2018

Nice approach~

@antidb

This comment has been minimized.

Copy link

@antidb antidb commented Sep 10, 2018

Thanks, it works on video from youtube.

@yuanchieh-cheng

This comment has been minimized.

Copy link

@yuanchieh-cheng yuanchieh-cheng commented Sep 14, 2018

Is there any way to rerange the timestamp of segments in m3u8 list?

The segment is not continuous so I want to rewrite the timestamp.

error is like Non-monotonous DTS in output stream 0:0

@magicdawn

This comment has been minimized.

Copy link

@magicdawn magicdawn commented Jun 15, 2019

trying to understand what the options mean

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

-bsf:a aac_adtstoasc

-c copy -vcodec copy

-crf 50

@shankarsundaram

This comment has been minimized.

Copy link

@shankarsundaram shankarsundaram commented Dec 9, 2019

you can use vlc to convert easily

@jcapinc

This comment has been minimized.

Copy link

@jcapinc jcapinc commented Jan 29, 2020

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

@suprnurd

This comment has been minimized.

Copy link

@suprnurd suprnurd commented Apr 8, 2020

Just what I was looking for, awesome! Thank you so much for sharing!

@cherkesgiller

This comment has been minimized.

Copy link

@cherkesgiller cherkesgiller commented Apr 8, 2020

Thank you so much, I appreciate it

@samelie

This comment has been minimized.

Copy link

@samelie samelie commented Apr 18, 2020

Works great on pbs.org since their single-page-app isn't understood by youtube-dl

@varenc

This comment has been minimized.

Copy link

@varenc varenc commented Jun 5, 2020

@magicdawn, most of the ffmpeg options here don't do anything so it's particularly confusing trying to understand them.

In most all situations you just need this:

ffmpeg -i "http://host/folder/file.m3u" -c copy file.mp4

or

echo "Enter m3u8 link:";read link;echo "Enter output filename:";read filename;ffmpeg -i "$link"  -c copy $filename.mp4

to breakdown the original command...

-c copy -vcodec copy

is redundant. -c copy says "for all streams, do a stream copy" (no re-encoding). And then -vcodec copy says "for the video stream[s], do a stream copy". -c copy is all that's needed. You could also do -vcodec copy -acodec copy or -codec copy since -c is just a short version of -codec.

-crf 50

As you pointed out, since there's no transcoding going on, this video quality flag does nothing. And if it did work, 50 is such low quality that you probably wouldn't like the result. Also this flag is only supported by some codecs. (I wish ffmpeg gave you a warning when you pass in a useless flag!)

-bsf:a aac_adtstoasc

These days ffmpeg is smart enough to automatically insert this filter when needed. IMHO it's cleaner to just rely on that rather than always inserting it even when it's not necessary. (like in non-AAC+MPEG-TS streams) If you turn on verbose messaging with -v verbose you'll see that ffmpeg informs you of this:

$  ffmpeg -i https://...m3u8 -v verbose -c copy test.mp4
...
Automatically inserted bitstream filter 'aac_adtstoasc'; args=''

You can pull all this together and test things by downloading a stream with and without all these options and see that the resulting files are identical!

$ ffmpeg -i https://../stream.m3u8 -c copy test1.mp4
$ ffmpeg -i https://../stream.m3u8 -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 test2.mp4
$ md5 test*.mp4
MD5 (test1.mp4) = 854e2beca4b3e516dd4cf147ca0521ee
MD5 (test2.mp4) = 854e2beca4b3e516dd4cf147ca0521ee

Another tip: if youtube-dl works but you want to control how ffmpeg downloads a stream without having to manually snoop for the .m3u8 file, just use youtube-dl's -g flag and it'll print out the m3u8 url and exit.

$ youtube-dl -g "https://host.com/some-webplay-video"

for example

$ youtube-dl -g https://www.pbs.org/video/east-bay-hip-hop-dance-in-richmond-ca-ng3v7e/
https://ga.video.cdn.pbs.org/videos/if-cities-could-dance/a7c8f330-2de4-4476-bb64-b23ae0bb2951/2000112404/hd-16x9-mezzanine-1080p/3f1sh5t6_richmond_iccd-16x9-1080p-1080p-6500k.m3u8

$ ffmpeg -i https://ga.video.cdn.pbs.org/videos/if-cities-could-dance/a7c8f330-2de4-4476-bb64-b23ae0bb2951/2000112404/hd-16x9-mezzanine-1080p/3f1sh5t6_richmond_iccd-16x9-1080p-1080p-6500k.m3u8 -c copy pbs-vid.mp4
@AshrayDesai

This comment has been minimized.

Copy link

@AshrayDesai AshrayDesai commented Jun 16, 2020

When I use this command:
ffmpeg -i "http://host/folder/file.m3u8" -c copy file.mp4

The resulting file.mp4 is always a video of different length -- sometimes 20min, sometimes, 15min, sometimes 5. Not only this, but the videos do not appear to start at the same time. Anyone know what could be happening?

@hmilz

This comment has been minimized.

Copy link

@hmilz hmilz commented Jun 25, 2020

$ youtube-dl -g https://www.pbs.org/video/east-bay-hip-hop-dance-in-richmond-ca-ng3v7e/
https://ga.video.cdn.pbs.org/videos/if-cities-could-dance/a7c8f330-2de4-4476-bb64-b23ae0bb2951/2000112404/hd-16x9-mezzanine-1080p/3f1sh5t6_richmond_iccd-16x9-1080p-1080p-6500k.m3u8

$ ffmpeg -i https://ga.video.cdn.pbs.org/videos/if-cities-could-dance/a7c8f330-2de4-4476-bb64-b23ae0bb2951/2000112404/hd-16x9-mezzanine-1080p/3f1sh5t6_richmond_iccd-16x9-1080p-1080p-6500k.m3u8 -c copy pbs-vid.mp4

This is exactly what youtube-dl does if you just invoke

$ youtube-dl https://www.pbs.org/video/east-bay-hip-hop-dance-in-richmond-ca-ng3v7e/

i.e. it uses ffmpeg (or avconv if you so wish) in the background. No need to do that manually.

@ilovefood2

This comment has been minimized.

Copy link

@ilovefood2 ilovefood2 commented Sep 28, 2020

i got Output file #0 does not contain any stream error, not sure why

@tocamgar

This comment has been minimized.

Copy link

@tocamgar tocamgar commented Oct 26, 2020

I received this response from ffmpeg
image
Then I tried: youtube-dl --no-part --restrict-filenames --user-agent "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/playlist.m3u8?pulse=assetsXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
And it worked, then I tested the original comand line (ffmpeg) and now it worked without problems
Don't know why. 🤷‍♀️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.