首页 编程教程正文

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

piaodoo 编程教程 2020-02-22 22:14:51 1774 0 python教程

本文来源吾爱破解论坛

本帖最后由 a1789043588 于 2020-1-26 16:28 编辑

代码写的比较烂,请大佬指点我的代码需要改善和优化的地方!
0,本人菜鸟,在设计这个工具中遇到了好几个问题没有解决:
(1)合并文件用windows的copy /b,但是windows控制台对命令长度要求是8k以内,文件数太多就没法一次合并成一个文件,有没有别的好办法?
(2)在用协程下载时速度快了好多,但是会遇到连接错误的情况,不知道这个怎么解决?
         感谢葫芦炒鸡蛋,copy /b问题已经解决。原来copy在合并时,当文件名是0,1,2,3,4...,合并顺序是0,1,10,100...。把文件名改成0001,0002,0003...就能依次序合并了。所以在合并前先修改一下文件名,然后直接copy /b * 电影名.mp4即可。合并和删除ts代码修改如下:
[Python] 纯文本查看 复制代码

def com_ts(movie_name,work_path):
    for a, b, files in os.walk(work_path):
        os.chdir(work_path)
        for i in files:
            if len(i)==1:
                new_name='000'+i
                os.rename(i, new_name)
            elif len(i)==2:
                new_name = '00' + i
                os.rename(i, new_name)
            elif len(i)==3:
                new_name = '0' + i
                os.rename(i,new_name)
            else:
                pass
    os.system('copy /b * '+movie_name+'.mp4')
def del_ts(work_path):
    os.chdir(work_path)
    for a,b,files in os.walk(work_path):
        for i in files:
            if '.' not in i:
                os.remove(i)

1,如何下载的?
(1)获取index.m3u8文件,改文件记录了每一小段视频的所在的网址。               我用的谷歌浏览器+DouYuVide插件,会自动获得该视频的index.m3u8文件。
效果如图:

index.m3u8文件内容如下:
[Asm] 纯文本查看 复制代码
#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,具体实现代码:
[Python] 纯文本查看 复制代码
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/')

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:https://www.piaodoo.com/7932.html

搜索