python+FFmpeg实现对m3u8文件内的ts视频多线程下载、解密、合并成MP4,并输出。

需求:把目标网站的电影下载到本地。

目标网站电影:《丛林奇航》电影完整版免费在线观看_天启影院

分析网站:

1,根据网页分析 该电影的m3u8是放在 index.m3u8里,网页里有两个 index.m3u8,选择第二个。(具体怎么分析网页,这里就不讨论了)

下载m3u8文件

# 下载m3u8
def down_m3u8(url):
    resp = requests.get(url, headers)
    text = resp.text
    with open("丛林奇航.m3u8", "w") as f:
        f.write(text)
    print("丛林奇航.m3u8下载完成")

2,对下载下来的 m3u8 分析,这里会发现是有经过AES-128加密,ts视频下载后会无法播放,所以还需要进行解密。

采用多线程下载ts视频

# 采用线程池下载m3u8里的ts
def down_ts():
    with open("./丛林奇航.m3u8", "r", encoding="utf-8") as f:
        # n = 0
        with ThreadPoolExecutor(10) as t:
            for n, line in enumerate(f):
                line = line.strip()
                if line.startswith("#"):
                    continue
                t.submit(ts_video, n, line)


# 下载ts视频 D:\\data\\movie_ts\\m1 为下载ts视频存放的路径
def ts_video(n, line):
    # 下载视频
    resp3 = requests.get(line)
    with open(f"D:\\data\\movie_ts\\m1\\{n}.ts", "wb") as f:
        f.write(resp3.content)
    print(n, "下载完成")

3,这里下载好的视频是有经过加密的,无法在播放器是直接看,接下来就要对下载好的加密ts视频进行解密

 解密ts视频

# 对下载t好的ts视频进行解密 D:\\data\\video\\m1\\ 为解密后ts存放的路径
def jiemi():
    f = open("./丛林奇航.m3u8", "r", encoding="utf-8")
    keys = []
    for file in f:
        key = re.findall(r'URI="(.*?)"', file) # 用正则匹配出 key
        if key:
            keys.append(key[0])
    key_url = keys[0]
    resp4 = requests.get(key_url)
    key = resp4.text
    key = key.encode("utf-8")
    aes = AES.new(key=key, IV=b"0000000000000000", mode=AES.MODE_CBC)
    download_path = "D:\\data\\movie_ts\\m1"
    all_ts = os.listdir(download_path)
    li = []
    for i in all_ts:
        i = i.split(".")[0]
        li.append(int(i))
    li.sort()
    for i in li:
        with open(f"D:\\data\\movie_ts\\m1\\{i}.ts", mode="rb") as f1, \
                open(f"D:\\data\\video\\m1\\2000{i}.ts", mode="wb") as f2:
            bs = f1.read()
            f2.write(aes.decrypt(bs))
        print(f"第{i}视频处理完毕")

解密好的ts视频

 解密好的ts视频是可以直接用播放器看的

4,对解密好的ts视频用 ffmpeg合成MP4视频

这里需要先安装 ffmpeg 

Windows:

1. 进入 http://ffmpeg.org/download.html#build-windows,点击 windows 对应的图标,进入下载界面点击 download 下载按钮,
2. 解压下载好的zip文件到指定目录
3. 将解压后的文件目录中 bin 目录(包含 ffmpeg.exe )添加进 path 环境变量中
4. DOS 命令行输入 ffmpeg -version, 出现以下界面说明安装完成:

Mac (打开终端(Terminal), 用 homebrew 安装):

brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora

Linux:

apt-get install ffmpeg libavcodec-extra

ffmpeg合成MP4视频 

# 对解密好的ts视频用 ffmpeg合成MP4视频
def movie_video():
    filePath = "D:\\data\\video\\m1"
    file_list = os.listdir(filePath)
    li = []
    for file in file_list:
        file = file.split(".")[0]
        li.append(int(file))
        li.sort()
    ts_file_name = []
    for i in li:
        i = str(i) + ".ts"
        ts_file_name.append(i)
    with open("D:\\data\\video\\m1\\file_list.txt", "w+") as f:
        for file in ts_file_name:
            f.write("file '{}'\n".format(file))
    print("file_list.txt已生成")
    txt_file = "D:\\data\\video\\m1\\file_list.txt"
    mp4 = "D:\\data\\movies\\丛林奇航.mp4"
    cmd = f"ffmpeg -f concat -i {txt_file} -c copy {mp4}"
    try:
        os.system(cmd)
    except Exception as e:
        print(e)
    print("done")

全部参考代码如下:

import re
import time
import os
import requests
from Crypto.Cipher import AES
from concurrent.futures import ThreadPoolExecutor

# 下载m3u8
def down_m3u8(url):
    resp = requests.get(url, headers)
    text = resp.text
    with open("丛林奇航.m3u8", "w") as f:
        f.write(text)
    print("丛林奇航.m3u8下载完成")


# 采用线程池下载m3u8里的ts
def down_ts():
    with open("./丛林奇航.m3u8", "r", encoding="utf-8") as f:
        # n = 0
        with ThreadPoolExecutor(10) as t:
            for n, line in enumerate(f):
                line = line.strip()
                if line.startswith("#"):
                    continue
                t.submit(ts_video, n, line)


# 下载ts视频
def ts_video(n, line):
    # 下载视频
    resp3 = requests.get(line)
    with open(f"D:\\data\\movie_ts\\m1\\{n}.ts", "wb") as f:
        f.write(resp3.content)
    # n += 1
    print(n, "下载完成")


# 对下载t好的ts视频进行解密
def jiemi():
    f = open("./丛林奇航.m3u8", "r", encoding="utf-8")
    keys = []
    for file in f:
        key = re.findall(r'URI="(.*?)"', file)
        if key:
            keys.append(key[0])
    key_url = keys[0]
    resp4 = requests.get(key_url)
    key = resp4.text
    key = key.encode("utf-8")
    aes = AES.new(key=key, IV=b"0000000000000000", mode=AES.MODE_CBC)
    download_path = "D:\\data\\movie_ts\\m1"
    all_ts = os.listdir(download_path)
    li = []
    for i in all_ts:
        i = i.split(".")[0]
        li.append(int(i))
    li.sort()
    for i in li:
        with open(f"D:\\data\\movie_ts\\m1\\{i}.ts", mode="rb") as f1, \
                open(f"D:\\data\\video\\m1\\2000{i}.ts", mode="wb") as f2:
            bs = f1.read()
            f2.write(aes.decrypt(bs))
        print(f"第{i}视频处理完毕")


# 对解密好的ts视频用 ffmpeg合成MP4视频
def movie_video():
    filePath = "D:\\data\\video\\m1"
    file_list = os.listdir(filePath)
    li = []
    for file in file_list:
        file = file.split(".")[0]
        li.append(int(file))
        li.sort()
    ts_file_name = []
    for i in li:
        i = str(i) + ".ts"
        ts_file_name.append(i)
    with open("D:\\data\\video\\m1\\file_list.txt", "w+") as f:
        for file in ts_file_name:
            f.write("file '{}'\n".format(file))
    print("file_list.txt已生成")
    txt_file = "D:\\data\\video\\m1\\file_list.txt"
    mp4 = "D:\\data\\movies\\丛林奇航.mp4"
    cmd = f"ffmpeg -f concat -i {txt_file} -c copy {mp4}"
    try:
        os.system(cmd)
    except Exception as e:
        print(e)
    print("done")


if __name__ == '__main__':
    url = "https://pps.sd-play.com/20211127/g8V4A0hE/1000kb/hls/index.m3u8"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
    }
    t_start = time.time()
    print("------------------开始下载m3u8----------------------------")
    down_m3u8(url)
    time.sleep(1)
    print("------------------开始下载ts视频----------------------------")
    down_ts()
    time.sleep(1)
    print("------------------开始下载解密ts视频----------------------------")
    jiemi()
    time.sleep(1)
    print("------------------开始下载合成MP4----------------------------")
    movie_video()
    t_end = time.time()
    t = t_end-t_start
    print(t)

提示:当代码运行到 如图 所示,这里是在合成视频,需要一定的时间,耐心等待完成就行。

 python 小白一个,不喜勿喷。希望对大家有所帮助 。。。。。。

最后,python大法好!

猜你喜欢

转载自blog.csdn.net/weixin_44002144/article/details/123036137