打印

Python下载m3u8视频

[复制链接]
1821|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
taosha126|  楼主 | 2019-7-25 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Python下载m3u8视频,支持多线程,断点下载(也可以修改后下载其他类型视频)
先上github地址:
https://github.com/tosobright/m3u8-Downloader

1.获取m3u8列表
flist = []
    key = ''

    all_content = requests.get(url).text

    if "#EXTM3U" not in all_content:
        print u"Not m3u8" + all_content.decode('GBK')

    if "EXT-X-STREAM-INF" in all_content:  # 第一层
        file_line = all_content.split("\n")
        for line in file_line:
            if '.m3u8' in line:
                url = url.rsplit("/", 1)[0] + "/" + line  # 拼出第二层m3u8的URL
                all_content = requests.get(url).text
                file_line = all_content.split("\n")

                for item in file_line:
                    if "#" not in item:
                        if item != "":
                            flist.append(url.rsplit("/", 1)[0] + "/" + item)
                    else:
                        if "#EXT-X-KEY" in item:  # 找解密Key
                            method_pos = item.find("METHOD")
                            comma_pos = item.find(",")
                            method = item[method_pos:comma_pos].split('=')[1]
                            print u"Decode Method:", method

                            uri_pos = item.find("URI")
                            quotation_mark_pos = line.rfind('"')
                            key_path = item[uri_pos:quotation_mark_pos].split('"')[
                                1]

                            key_url = url.rsplit(
                                "/", 1)[0] + "/" + key_path  # 拼出key解密密钥URL
                            res = requests.get(key_url)
                            key = res.content
                            print u"key:", key

    return flist, key

2.根据解析的m3u8地址进行下载,并记录下当前下载的进度点

length = len(playlists)
    if len(key):  # AES 解密
        cryptor = AES.new(key, AES.MODE_CBC, key)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"}

    # 增加断点续传
    logfilename = os.path.split(filepath)[1].split('.')[0] + '.lf'
    logfile = os.path.split(filepath)[0] + '\\' + logfilename
    if os.path.exists(logfile):
        with open(logfile, 'r') as f:
            DownLoadedIndex = int(f.read())
    else:
        DownLoadedIndex = -1

    for index, url in enumerate(playlists):
        # 是否下载判定
        if index > DownLoadedIndex:
            notOK = True
            while notOK:
                try:
                    res = requests.get(url, timeout=5, headers=headers)
                    #print res.content
                    # s.decode('GBK')
                    if res.status_code == 200:
                        print (os.path.split(filepath)[
                            1] + " : " + str(index)+"|"+str(length-1) + "   ").decode('GBK')
                        if len(key):  # AES 解密
                            with open(filepath, 'ab') as f:
                                f.write(cryptor.decrypt(res.content))
                        else:
                            with open(filepath, 'ab') as f:
                                f.write(res.content)
                        time.sleep(1)
                        notOK = False
                        with open(logfile, 'w') as f:
                            f.write(str(index))

                except Exception as e:
                    print (os.path.split(filepath)[
                        1] + '  retry...' + str(e)).decode('GBK')
                    time.sleep(5)
3.开启多线程进行下载
playlists, key = GetPlayLists(url)
    if len(playlists) != 0:
        print 'Total Length:', len(playlists)

        if len(playlists) <= process:
            process = len(playlists)

        splitlength = len(playlists)/process + 1
        splitlist = [playlists[i:i+splitlength]
                     for i in range(0, len(playlists), splitlength)]
        print splitlength, len(splitlist)
        param = []
        for index, lists in enumerate(splitlist):
            fp = filepath.rsplit("\\", 1)[
                0] + "\\" + str(index).zfill(3)+filepath.rsplit("\\", 1)[1]
            dict = {'filepath': fp, 'playlists': lists, 'key': key}
            param.append((None, dict))

        pool = threadpool.ThreadPool(process)
        requests = threadpool.makeRequests(download, param)
        [pool.putRequest(req) for req in requests]
        pool.wait()
        pool.dismissWorkers(process)

        return True
    else:
        return False


使用特权

评论回复

相关帖子

沙发
gaoyang9992006| | 2019-8-31 23:37 | 只看该作者
手机视频一般用的这个传输的,是个简单的文本文件,然后不知道视频文件是怎么分存的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

18

帖子

0

粉丝