• Python3 根据m3u8下载视频,批量下载ts文件并且合并


    Python3 根据m3u8下载视频,批量下载ts文件并且合并

    m3u8是苹果公司推出一种视频播放标准,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求,是现在比较流行的一种加载方式,诸如腾讯视频之类大多都是切割成ts流进行加载。

    示例代码:

    import os, shutil
    import urllib.request, urllib.error, requests
    
    # 打开并读取网页内容
    def getUrlData(url):
        try:
            urlData = urllib.request.urlopen(url, timeout=20)  # .read().decode('utf-8', 'ignore')
            return urlData
        except Exception as err:
            print(f'err getUrlData({url})
    ', err)
            return -1
    
    # 下载文件-urllib.request
    def getDown_urllib(url, file_path):
        try:
            urllib.request.urlretrieve(url, filename=file_path)
            return True
        except urllib.error.URLError as e:
            # hasttr(e, 'code'),判断e 是否有.code属性,因为不确定是不是HTTPError错误,URLError包含HTTPError,但是HTTPError以外的错误是不返回错误码(状态码)的
            if hasattr(e, 'code'):
                print(e.code)  # 打印服务器返回的错误码(状态码),如403,404,501之类的
            elif hasattr(e, 'reason'):
                print(e.reason)  # 打印错误原因
    
    
    def getVideo_urllib(url_m3u8, path, videoName):
        print('begin run ~~
    ')
         # urlData = getUrlData(url_m3u8).readlines()
        urlData = getUrlData(url_m3u8)
        num = 0
        tempName_video = os.path.join(path, f'{videoName}.ts')  # f'{}' 相当于'{}'.format() 或 '%s'%videoName
        # print(urlData)
        for line in urlData:
            # 解码,由于是直接使用了所抓取的链接内容,所以需要按行解码,如果提前解码则不能使用直接进行for循环,会报错
            # 改用上面的readlines()或readline()也可以,但更繁琐些,同样需要按行解码,效率更低
            url_ts = line.decode('utf-8')
            tempName_ts = os.path.join(path, f'{num}.ts')  # f'{}' 相当于'{}'.format()
            if not '.ts' in url_ts:
                continue
            else:
                if not url_ts.startswith('http'):  # 判断字符串是否以'http'开头,如果不是则说明url链接不完整,需要拼接
                    # 拼接ts流视频的url
                    url_ts = url_m3u8.replace(url_m3u8.split('/')[-1], url_ts)
            print(url_ts)
            getDown_urllib(url_ts, tempName_ts)  # 下载视频流
            if num == 0:
                # 重命名,已存在则自动覆盖
                shutil.move(tempName_ts, tempName_video)
                num += 1
                continue
            cmd = f'copy /b {tempName_video}+{tempName_ts} {tempName_video}'
            res = os.system(cmd)
            if res == 0:
                os.system(f'del {tempName_ts}')
                if num == 20:  # 限制下载的ts流个数,这个视频挺长有四百多个.ts文件,所以限制一下
                    break
                num += 1
                continue
            print(f'Wrong, copy {num}.ts-->{videoName}.ts failure')
            return False
        os.system(f'del {path}/*.ts')  # 调用windows命令行(即cmd)工具,运行命令
        filename = os.path.join(path, f'{videoName}.mp4')
        shutil.move(tempName_video, filename)
        print(f'{videoName}.mp4 finish down!')
    
    
    if __name__ == '__main__':
        url_m3u8 = 'http://wscdn.alhls.xiaoka.tv/201886/2f5/75a/HoHdTc1LjUaBjZbJ/index.m3u8'
        path = r'E:pydevworkspacesprojectproductepgwvideos'
        videoName = url_m3u8.split('/')[-2]
        getVideo_urllib(url_m3u8, path, videoName)

    注:(1)仅限windows下使用,如果要在Linux上使用需要修改合并命令;

            (2)修改文件名时,特意选择shutil模块(可以看作os的高级版)的move方法,虽然move主要是用来移动文件的,重命名算是附带的,不过强制覆盖的特点在这里很有用,避免中断后重新下载时重命名产生异常。

  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/lizm166/p/10262394.html
Copyright © 2020-2023  润新知