Python 神器:一键下载 M3U8 并转换为 MP4 格式

在这个数字时代,我们经常在网页上遇到各种精彩的视频,但往往只能观看而无法下载。今天,我将向大家介绍如何使用 Python 自动下载网页中的 M3U8 链接,并将其转换为 MP4 格式,让你轻松保存喜欢的视频!

一、准备工作

首先,确保你已经安装了 ffmpeg。如果还没有安装,可以通过以参考这里安装:https://wizops.net/archives/202404/323.html

二、代码流程

  • 下载 M3U8 文件保存到临时目录。
  • 下载 key 文件保存到临时目录。
  • 生成本地 M3U8 文件内容保存到临时目录。
  • 下载 ts 文件保存到临时目录下的index目录。
  •  使用ffmpeg将m3u8转换成mp4文件
  • 三、代码实现

    import os
    import urllib3
    import requests
    import subprocess
    from m3u8 import M3U8
    from tenacity import retry, wait_random, stop_after_attempt
    from gevent.pool import Pool
    urllib3.disable_warnings()
    
    pool = Pool(10)
    
    @retry(stop=stop_after_attempt(3), wait=wait_random(2, 5))
    def request(url):
        """发送请求"""
        try:
            res = requests.get(url, verify=False, timeout=5)
            return res
        except Exception as e:
            print(url, e)
            raise e
    
    
    def download_segment(url, path):
        """下载ts文件"""
        filename = url.split("/")[-1]
        file = os.path.join(path, filename)
        if os.path.exists(file):
            return 
    
        res = request(url)
        with open(file, "wb")as f:
            f.write(res.content)
    
    
    def convert_mp4(path, output):
        # 使用FFmpeg将local.m3u8转换为一个MP4文件    ffmpeg -allowed_extensions ALL -i index.m3u8 -c copy xxx.mp4
        # m3u8文件中有key需要带参数-allowed_extensions ALL
        subprocess.call(['ffmpeg', '-allowed_extensions', 'ALL', '-i', 'local.m3u8', '-c', 'copy', output], cwd=path)
    
    def download_m3u8(url, path, output):
        """
        下载单个m3u8主程序
        url: m3u8链接url
        path: 单个m3u8目录
        output: 转换输出文件路径名
        """
        base_url = url.rsplit("/", 1)[0]
        # 创建目录
        segment_dir = os.path.join(path, "index")
        if not os.path.exists(segment_dir):
            os.makedirs(segment_dir)
    
        # 下载M3U8文件
        m3u8_file_name = os.path.join(path, "index.m3u8")
        res = request(url)
        with open(m3u8_file_name, "w", encoding="utf-8")as f:
            f.write(res.text)
    
        # 解析M3U8文件
        m3u8_obj = M3U8(res.text)
    
        print(m3u8_obj.keys)
        # 下载key文件 
        for item in m3u8_obj.keys:
            if item:
                key_url = item.uri if item.uri.startwith("http") else f"{base_url}/{item.uri}"
                key_file_name = os.path.join(path, item.uri)
                res = request(key_url)
                with open(key_file_name, "w", encoding="utf-8")as f:
                    f.write(res.text)
    
        segments = []
        # 生成新的本地M3U8文件内容
        for segment in m3u8_obj.segments:
            segments.append(segment.uri)
            segment.uri = "index/" + segment.uri.split("/")[-1]
    
        # 保存M3U8文件
        local_file_name = os.path.join(path, "local.m3u8")
        with open(local_file_name, 'w') as f:
            f.write(m3u8_obj.dumps())
    
        # 下载ts文件
        for url in segments:
            pool.spawn(download_segment, url, segment_dir)
        pool.join()
    
        # ts文件下载完成, 转换成mp4文件
        if len(segments) == len(os.listdir(segment_dir)):
            convert_mp4(path, output)
    
    if __name__ == "__main__":
        url = "https://v3.mstopq.com/202302/26/E92zcVVNkT1/video/1000k_0X720_64k_25/hls/index.m3u8"
        cur_path = os.path.abspath(os.path.dirname(__file__))
        path = os.path.join(cur_path, "终结者创世纪_tmp")
        output = os.path.join(cur_path, "终结者创世纪.mp4")
        download_m3u8(url, path, output)

    三、注意事项

  • 确保已经安装了 ffmpeg,并且在系统路径中可以访问到。
  • 输出路径必须存在,否则可能会出现错误。
  • 根据实际情况,可能需要根据 M3U8 文件的具体内容调整 ffmpeg 命令的参数。
  • 通过这个简单的示例,你可以使用 Python 自动下载网页中的 M3U8 链接并将其转换为 MP4 格式。现在,你可以轻松保存喜欢的视频,随时随地观看啦!希望这个技巧对你有所帮助。如果有任何问题或建议,欢迎在评论中留言!

    作者:龙行天5

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python 神器:一键下载 M3U8 并转换为 MP4 格式

    发表回复