zhouxinhuagg

python协程下载某网站无加密m3u8视频下载合并为mp4

作者: zhouxinhuagg 发布时间: 2020-01-26 4.11K 人阅读

python协程下载某网站无加密m3u8视频下载合并为mp4

代码写的比较烂,请大佬指点我的代码需要改善和优化的地方!
0,本人菜鸟,在设计这个工具中遇到了好几个问题没有解决:
(1)合并文件用windows的copy /b,但是windows控制台对命令长度要求是8k以内,文件数太多就没法一次合并成一个文件,有没有别的好办法?
(2)在用协程下载时速度快了好多,但是会遇到连接错误的情况,不知道这个怎么解决?
1,如何下载的?
(1)获取index.m3u8文件,改文件记录了每一小段视频的所在的网址。               我用的谷歌浏览器+DouYuVide插件,会自动获得该视频的index.m3u8文件。
效果如图:

index.m3u8文件内容如下:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:7
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.960000,
/hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00000.ts
#EXTINF:3.040000,
/hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00001.ts
#EXTINF:5.120000,
/hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_00002.ts
... ...

(2)下载每一小段的ts视频。
             url是index.m3u8下载地址的域名部+/hls/20190515/2ae3349c3c93cf8928a4eba8e1b59d56/1557914849/film_***.ts。
(3)使用gevent.monkey协程下载速度要快很多。

2,如何合并的?
使用windows控制台的copy /b命令合并的,但是该命令在我的win7下限制命令长度为8k。
本工具在文件总数超过1800时不得不将视频合并成两部分,

3,具体实现代码:

import gevent
import gevent.monkey
gevent.monkey.patch_all()
import requests
import re
import os
import time
def get_file_num(path):        #获取path目录下的文件总数
    for a,b,files in os.walk(path):
        return len(files)
def get_ts(url,name,work_path):  #下载一个ts文件。url是下载地址,work_path是要保存磁盘的目录。
    print('start ' ,name)
    urls = 'https://1*'+url
    headers={'Connection': 'close'}
    try:  #下载太快出现连接错误时的解决方法。
        response = requests.get(urls,headers=headers)   
    except:
        urls = 'https://2*' + url
        try:
            response = requests.get(urls, headers=headers)
        except:
            urls = 'https://3*' + url
            try:
                response = requests.get(urls, headers=headers)
            except:
                print('下载失败:',name)
                return
    ts = response.content
    with open(work_path + name, 'wb') as f:
        f.write(ts)
    print(urls,'finish')
def get_url(path):  #从磁盘的path路径读取index.m3u8文件并通过正则将每一个ts文件下载地址的后边部分形成一个list。
    pattern = re.compile(r'/hls.+ts')
    with open(path,'r') as f:
        l=pattern.findall(f.read()[112:])
        return l
def downmovie(m3u8_path,work_path): #进行下载
    os.chdir(work_path)
    path = m3u8_path
    l = get_url(path)
    p = []
    for i,url in enumerate(l):
        if os.path.exists(str(i)):
            pass
        else:
            p.append(gevent.spawn(get_ts, url, str(i),work_path))
    gevent.joinall(p)
    f_num = get_file_num(work_path)
    if f_num!=len(l):  #验证是否下载完所有的ts文件,没有的话等30s再去下载。(解决暂时封ip)
        print('部分没有下载完成,请30s后再次启动下载!')
def com_ts(movie_name,work_path):  #合并ts文件为一个或两个MP4
    os.chdir(work_path)
    tss = ''
    f_num = get_file_num(work_path)
    for i in range(f_num):
        if i>1800:
            break
        tss = tss + str(i) + '+'
    shell_str = 'copy /b ' + tss[:-1] + ' '+movie_name+'.mp4'
    print(shell_str)
    os.system(shell_str)
    if i>1800:
        for i in range(1800, f_num):
            tss = tss + str(i) + '+'
        shell_str = 'copy /b ' + tss[:-1] + ' ' + movie_name + '2.mp4'
        print(shell_str)
        os.system(shell_str)
 
def del_ts(work_path):  #删除所有ts文件
    f_num = get_file_num(work_path)
    for i in range(f_num-1):
        os.remove(work_path+str(i))
 
if __name__ == '__main__':  #下边三个函数每次只能运行一个,否则会出错。确保全部ts下载完成再去合并,确保合并完再去删除。
    downmovie('C:/Users/admin/Desktop/index.m3u8','C:/Users/admin/Desktop/movies/')
    com_ts('电影名','C:/Users/wangzi/Desktop/movies/')
    del_ts('C:/Users/admin/Desktop/movies/')

 

本文最后更新于2020年1月26日,若涉及的内容可能已经失效,直接留言反馈补链即可,我们会处理,谢谢
本站所有资源收集于网络,如有侵权违规请联系联系客服处理删帖,谢谢
52草根资源 » python协程下载某网站无加密m3u8视频下载合并为mp4

常见问题FAQ

1.关于新手解压出错 必看(附电脑+安卓WINRAR APP)
新手必看 本站资源解压教程:http://www.52cgzys.com/76304/
2.本站Telegram群组链接
本站Telegram群组链接:https://t.me/joinchat/ElyDb9Es_YNjYjdl
3.所有礼包码下载地址:http://www.52cgzys.com/422289/
所有礼包码下载地址:http://www.52cgzys.com/422289
4.各类问题及解决处理方法合集
各类问题及解决处理方法合集:http://www.52cgzys.com/zhanwu/xinshou/

发表回复

提供最优质的资源集合

立即查看 申请友链