python协程下载某网站无加密m3u8视频下载合并为mp4
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日,若涉及的内容可能已经失效,直接留言反馈补链即可,我们会处理,谢谢
常见问题FAQ
- 1.关于新手解压出错 必看(附电脑+安卓WINRAR APP)
- 新手必看 本站资源解压教程:http://www.52cgzys.com/76304/
- 2.本站Telegram群组链接
- 3.所有礼包码下载地址:http://www.52cgzys.com/422289/
- 4.各类问题及解决处理方法合集