20
votes

I want to download M3U8 file chunks (HLS) and store that video (after decrypting it) for later viewing. I have made a demo to play M3U8 file but I want to download video data for later view.

5
How are you playing the HLS stream? In-browser with a normal <video> tag?Brad
I am playing HLS in AVPlayerNSPratik
Which step are you having trouble with? You need to download the video data, decrypt it with the decryption key and save the resulting data to a file. Or are you having trouble with playing back the resulting file?vipw
I have trouble on how to download M3U8 file data. But, my requirement is changed now. MP4 will be downloaded for later viewing. While in case of streaming, encrypted HLS needs to be played on iOS side. How would I play encrypted HLS on iOS ?NSPratik
@NSPratik, thx for answer. I've found this github.com/kencool/KSHLSPlayer Looks like someone can store a video from stream. I'm trying to compile and check it. Maybe it can be useful.Dmitry L.

5 Answers

49
votes

You can use ffmpeg to download and decode the HTTP-LS stream:

ffmpeg -i http://example.org/playlist.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4

There is an iOS version of ffmpeg available.

5
votes

This Perl script is a good fetcher: https://github.com/osklil/hls-fetch

Steps:

wget https://raw.githubusercontent.com/osklil/hls-fetch/master/hls-fetch
chmod +x hls_fetch
./hls_fetch --playlist "THE_URL"

Replace THE_URL with the full URL of your M3U8 playlist (or try other options with --help).

Bonus: If you have missing Perl's JSON module (as I had), simply run sudo cpan JSON.

4
votes

There also exists a Chrome extension that makes a whole video from m3u8 chunks, here's the link HLS Video Saver

1
votes

url: https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8

Step-1: ffmpeg -i 'https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8' -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -b:a 128k -c:v h264 -profile:v main -crf 20 -g 48 -keyint_min 48 -sc_threshold 0 -b:v 2500k -maxrate 2675k -bufsize 3750k -hls_time 10 -hls_playlist_type vod -hls_segment_filename my_hls_video/720p_%03d.ts my_hls_video/720p.m3u8

Step-2:

-i 'https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8' :=> Set https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8 as the video source source.

-vf "scale=w=1280:h=720:force_original_aspect_ratio=decrease" :=> Scale video to maximum possible within 1280x720 while preserving aspect ratio

-c:a aac -ar 48000 -b:a 128k :=> Set audio codec to AAC with sampling of 48kHz and bitrate of 128k

-c:v h264 :=> Set video codec to be H264 which is the standard codec of HLS segments

-profile:v main :=> Set H264 profile to main - this means support in modern devices read more

-crf 20 :=> Constant Rate Factor, high level factor for overall quality

-g 48 -keyint_min 48 :=> IMPORTANT create key frame (I-frame) every 48 frames (~2 seconds) - will later affect correct slicing of segments and alignment of renditions

-sc_threshold 0 :=> Don't create key frames on scene change - only according to -g

-b:v 2500k -maxrate 2675k -bufsize 3750k :=> Limit video bitrate, these are rendition specific and depends on your content type - read more

-hls_time 4 : :=> Segment target duration in seconds - the actual length is constrained by key frames

-hls_playlist_type vod :=> Sdds the #EXT-X-PLAYLIST-TYPE:VOD tag and keeps all segments in the playlist

-hls_segment_filename beach/720p_%03d.ts :=> - explicitly define segments files names my_hls_video/720p.m3u8 - path of the playlist file - also tells ffmpeg to output HLS (.m3u8)