m3u8视频通用下载器

本文介绍了一款用Python编写的m3u8视频下载器,旨在帮助用户从非商业性网站下载m3u8视频。同时提供了一个m3u8视频解析器,用于从视频播放链接中获取m3u8地址。代码可能包含兼容性处理,适用于处理不同格式的m3u8内容。注意,作者强调脚本仅供技术学习和研究,禁止用于非法用途,并且明确不承担任何法律责任。
摘要由CSDN通过智能技术生成

闲来无事,写了个m3u8视频下载器,分享给各位(好处不多说!都懂!),如果有什么不对的地方,还请指正。另外还有m3u8视频解析器,通过视频播放链接(非商业性网站)解析出m3u8地址,然后再通过m3u8下载器进行下载,如果有需要的小伙伴请私信。

中间可能会有些看上去冗余的代码,主要是为了兼容各种稀奇古怪的m3u8内容。

脚本仅用于技术学习与研究,请勿用于任何非法用途,否则后果自负,本作者不承担任何法律责任。


原创文章,转载请注明出处,谢谢!https://blog.csdn.net/weixin_36381802/article/details/113694338


环境: pip install gevent requests loguru pycryptodome


# -*- coding:utf-8 -*-

"""
NAME: m3u8视频下载器
VERSION: v1.0
DATE: 2021-02-05
TIPS:
  1.若部分视频无法播放,建议更改文件名后缀或切换其它播放器(QuickTime、WindowsMedia等)进行尝试;
  2.在MacOS或Linux系统上运行前请确认已安装合并视频片段所使用的工具ffmpeg(Windows无视);
  3.仅支持下载m3u8类型视频,mp4等链接暂不支持(普通下载器满大街都是);
  4.脚本仅用于技术学习与研究,请勿用于任何非法用途,否则后果自负,本作者不承担任何责任。
"""


import argparse
import os
import platform
import re
import shutil
import time
from datetime import datetime
from urllib.parse import urljoin

import gevent
from gevent.pool import Pool
from gevent import monkey; monkey.patch_all()

import requests
import urllib3
from Crypto.Cipher import AES

# 自定义日志显示格式
from os import environ
environ['LOGURU_FORMAT'] = "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level:<5}</level> | <level>{message}</level>"
from loguru import logger

# logger.add('m3u8.log', level='DEBUG', format='{time:YYYY-MM-DD HH:mm:ss} {level:<5} {line} {message}')
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class M3u8VideoDownloader:
    headers = {
   
        'Accept': '*/*',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
    }

    def __init__(self, m3u8_url, download_path=None, video_name=None, is_del_clip=True, test_download_num=0,
                 retry_count=10, thread_num=30, dec_func=None, m3u8_content_plaintext=None):
        """
        :param m3u8_url: m3u8链接
        :param download_path: 下载路径
        :param video_name: 视频名称(不能出现括号)
        :param is_del_clip: 合并视频完成后是否删除原片段
        :param test_download_num: 测试下载视频数量
        :param retry_count: 单个视频片段下载失败重试次数
        :param thread_num: 下载线程数
        :param dec_func: m3u8内容解密函数(内容被加密时可传入解密函数,或直接将解密后的明文内容传递给参数m3u8_content_plaintext)
        :param m3u8_content_plaintext: 已解密的m3u8明文内容
        """
        self.m3u8_url = m3u8_url
        self.download_path = download_path
        self.cache_path = None         # 临时缓存路径
        self.video_name = video_name or str(int(time.time()))
        self.video_name_suffix = '.mp4'  # 文件类型后缀
        self.is_del_clip = is_del_clip
        self.test_download_num = test_download_num
        self.retry_count = retry_count
        self.thread_num = min(thread_num, 50)
        self.max_merge_num = 500       # 单次合并文件最大数量
        self.dec_func = dec_func
        self.m3u8_content_plaintext = m3u8_content_plaintext
        self.key_url = None
        self.key = None
        self.iv = None
        self.decipher = None
        self.video_clip_list = []      # 视频片段名称列表
        self.total_duration = 0        # 视频总时间(分钟)
        self.total_video_clip_num = 0  # 视频片段数量
        self.download_num = 0          # 已下载数量
        self.total_download_size = 0   # 总下载大小
        self.is_special_link = False   # 视频片段链接未带后缀(例`.ts`)时为True,一般出现在m3u8内容被加密的视频网站

    def fetch(self, url, binary=False):
        resp = requests.get(url, headers=self.headers, timeout=30, verify=False)
        status_code = resp.status_code
        if status_code != 200:
            raise Exception(f'请求失败({status_code}):{url}')
        if binary:
            return resp.content
        return resp.content.decode()

    def get_m3u8_content(self):
        """获取m3u8内容"""
        logger.info(f'M3U8链接:{self.m3u8_url}')
        try:
            m3u8_content = self.fetch(self.m3u8_url)
        except Exception as e:
            raise Exception(f'获取m3u8内容失败({self.m3u8_url}):{repr(e)}')

        # 如果内容被加密,需要通过传入的解密函数进行解密
        if self.dec_func:
            try:
                m3u8_content = self.dec_func(m3u8_content)
            except Exception as e:
                raise Exception(f'解密m3u8内容失败({self.m3u8_url}):{repr(e)}')

        if '#EXTM3U' not in m3u8_content:
            raise Exception(f'错误的M3U8信息,请确认链接是否正确:{self.m3u8_url}<{m3u8_content}>')
        if '#EXT-X-STREAM-INF' in m3u8_content:
            m3u8_url_list = [line for line in m3u8_content.split('\n') if line.find('.m3u8') != -1]
            if len(m3u8_url_list) > 1:
                logger.info(f'发现{len(m3u8_url_list)}个m3u8地址:{m3u8_url_list}')
            self.m3u8_url = urljoin(self.m3u8_url, m3u8_url_list[0])
            return self.get_m3u8_content()
        # logger.info(f'M3U8内容已获取完成:{self.m3u8_url}')
        return m3u8_content

    def parse_m3u8_info(self, m3u8_content):
        """解析m3u8文件:获取解密key、iv、视频url列表"""
        all_lines = m3u8_content
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Python是一种功能强大且易于学习的编程语言,它具有丰富的库和工具,可用于各种开发任务。M3U8是一种多媒体播放列表文件格式,常用于网络视频的流媒体传输。在Python中,我们可以使用多线程来实现一个M3U8多线程下载。 首先,我们需要使用requests库来获取M3U8文件的内容。使用requests库发送HTTP请求,并将M3U8文件的内容保存到本地。 接下来,我们需要解析M3U8文件,提取出其中的所有视频片段的URL。可以使用正则表达式或其他方法来实现。 然后,我们可以使用多线程来并发地下载视频片段。通过创建多个线程,并分配给每个线程不同的视频片段URL,可以同时下载多个视频片段,从而加快下载速度。 在每个线程中,我们可以使用requests库来发送HTTP请求,并将视频片段保存到本地。可以自定义保存位置和文件名。 最后,我们可以等待所有线程下载完成后,合并所有视频片段,生成完整的视频文件。可以使用Python的文件操作来实现。 需要注意的是,在多线程下载时,我们还需要处理线程间的同步和互斥问题,以确保线程安全。 总结起来,一个Python M3U8多线程下载的实现过程包括获取M3U8文件、解析M3U8文件、并发下载视频片段、合并视频片段等步骤。使用Python的多线程编程可以提高下载速度,并且可以灵活地根据需要进行调整和优化。 ### 回答2: Python m3u8多线程下载是一个用Python编写的工具,用于下载m3u8视频文件。 m3u8是一种视频播放列表文件格式,它包含了视频的分片链接地址。通常情况下,m3u8文件会将一个完整的视频分成多个小的ts文件,并将这些小文件的下载地址放在m3u8文件中。因此,如果我们想要下载一个m3u8视频,我们需要逐个下载这些小文件,并将它们合并成一个完整的视频。 多线程下载是一种并发的下载方式,它可以加快下载速度。使用多线程下载可以同时下载多个分片文件,并且可以利用计算机的多核心处理,实现更高效的下载Python提供了多线程编程的支持,我们可以利用Python的threading模块来实现多线程下载。首先,我们需要解析m3u8文件,获取其中的分片文件链接地址。然后,我们创建多个下载线程,每个线程负责下载一个分片文件。每个线程下载完一个分片文件后,将其保存在本地存储。最后,我们可以使用其他工具将这些分片文件合并成一个完整的视频文件。 多线程下载的好处是可以减少下载时间,提高下载效率。然而,需要注意的是,多线程下载也会增加网络带宽的使用,可能会对服务造成一定的负载。因此,在使用多线程下载时,我们需要注意合理设置线程数量,避免对服务造成过大的压力。 总之,Python m3u8多线程下载是一个方便快捷的工具,可以帮助我们高效地下载m3u8视频文件。 ### 回答3: Python m3u8多线程下载是一个用Python编写的工具,用于下载m3u8视频文件。m3u8是一种基于HTTP的流媒体传输协议,常用于视频直播和点播。 使用多线程下载可以加快下载速度,提高效率。程序首先需要解析m3u8文件,获取视频的各个分片(或者说ts文件)的URL地址。然后,使用多线程技术,同时从不同的服务下载不同的分片,并将它们合并成一个完整的视频文件。 在Python中,我们可以使用多线程库(如threading)来创建和管理线程。在每个线程中,我们可以使用HTTP库(如requests)来发送下载请求,并将分片保存到本地。 为了提高下载速度,我们可以根据网络环境和计算机配置来确定线程的数量,通常建议使用2到4个线程。 此外,还可以通过设置超时时间和重试机制来处理下载中的错误和异常情况,并在下载完成后进行一些清理工作。 总的来说,Python m3u8多线程下载是一个方便实用的工具,可以帮助用户快速下载m3u8视频文件,并提供了一些自定义选项来满足不同的需求。使用这个工具,用户可以更方便地获取和保存自己想要的视频内容。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值