Download encrypted HTTP live streaming video
Tags: linux, media
Published: 2024-01-31 19:01:06

## Notice

I wrote this article and was originally published on [Qiita](https://qiita.com/saladlam/items/050f018bca58ad7a91a7) on 18 March 2023.

---

# m3u8 file

Belows is an example of streaming video definition file. Meaning of directive is shown in [here](https://en.wikipedia.org/wiki/M3U). It can be processed by HTML5 player such as [DPlayer](https://github.com/DIYgod/DPlayer).

```text
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://www.example.com/video/b1cf799d0c2d9400fb437c1e912bfa8f/4433218.key",IV=0xed580cc71ef06c8e3cd6941e75a86f27
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i0.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i1.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i2.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i3.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i4.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i5.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i6.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i7.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i8.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i9.ts
#EXTINF:
https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i10.ts
#EXT-X-ENDLIST
```

This video contains 11 segments, is encrypted by AES-128(aes-128-cbc), key can be retrieved on https://www.example.com/video/b1cf799d0c2d9400fb437c1e912bfa8f/4433218.key (128-bit binary format), initialization vector is ed580cc71ef06c8e3cd6941e75a86f27 (hex format).

# Decrypt video segment

First to download key file and convert binary format of key to hex format

```sh
wget "https://www.example.com/video/b1cf799d0c2d9400fb437c1e912bfa8f/4433218.key"

xxd -ps 4433218.key
dd82d738191c7ec0cc78fa731230cbb1
```

Then download video segment and decrypt it

```sh
wget https://video.example.com/b1cf799d0c2d9400fb437c1e912bfa8f/i0.ts

openssl enc -nosalt -aes-128-cbc -d -in i0.ts -out d0.ts -K dd82d738191c7ec0cc78fa731230cbb1 -iv ed580cc71ef06c8e3cd6941e75a86f27
```

# Simple way to download

Having this m3u8 file, video can be downloaded, reassembled and decrypted by using ffmpeg. Command below can download video without re-encoding.

```sh
ffmpeg -protocol_whitelist file,tcp,https,tls,crypto -i input.m3u8 -c copy output.mp4
```

In fact, it is not recommand to download video segment by ffmpeg directly. First ffmpeg does not support retry, if one segment cannot be downloaded, ffmpeg will skip this segment and move on next segment. Then in some website video segments cannot be downloaded without providing additional HTTP headers, ffmpeg also does not support this.

The better ways is first to download video segments by wget

```sh
wget -i input.m3u8 --header="..." --header="..."
```

Then to edit m3u8 file, to remove HTTP path of video segment.

```text
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://www.example.com/video/b1cf799d0c2d9400fb437c1e912bfa8f/4433218.key",IV=0xed580cc71ef06c8e3cd6941e75a86f27
#EXTINF:
i0.ts
#EXTINF:
i1.ts
#EXTINF:
i2.ts
#EXTINF:
i3.ts
#EXTINF:
i4.ts
#EXTINF:
i5.ts
#EXTINF:
i6.ts
#EXTINF:
i7.ts
#EXTINF:
i8.ts
#EXTINF:
i9.ts
#EXTINF:
i10.ts
#EXT-X-ENDLIST
```

Finally using ffmpeg to decrypt and reassemble

```sh
ffmpeg -protocol_whitelist file,tcp,https,tls,crypto -i input_modify.m3u8 -c copy output.mp4
```