python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频「建议收藏」

python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频「建议收藏」一些网站会提供m3u8视频地址,以供下载观看。或者一些网站经过分析后发现是使用m3u8格式进行播放的,这时使用m3u8的地址链接就可以下载到相应的视频。一、关于m3u8:(https://blog.csdn.net/baidu_34418350/article/details/64922512)m3u8是苹果公司推出一种视频播放标准,是m3u的一种,不过编码方式是utf-8,是一种…

大家好,又见面了,我是你们的朋友全栈君。

一些网站会提供m3u8视频地址,以供下载观看。或者一些网站经过分析后发现是使用m3u8格式进行播放的,这时使用m3u8的地址链接就可以下载到相应的视频。

 

一、关于m3u8:(https://blog.csdn.net/baidu_34418350/article/details/64922512)

m3u8是苹果公司推出一种视频播放标准,是m3u的一种,不过 编码方式是utf-8,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求。

示例链接:http://cdn.can.cibntv.net/12/201702161000/rexuechangan01/rexuechangan01.m3u8

 

第一层

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2650800,RESOLUTION=1920×1080
1.m3u8

观察数据吗,没有用http://开头时,不是真正路径,需要拼接字符串再次请求:http://cdn.can.cibntv.net/12/201702161000/rexuechangan01/1.m3u8 得到数据

 

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:14
#EXTINF:11.480, 
20170215T224129-1-0.ts
#EXTINF:11.480, 
20170215T224129-1-1.ts
#EXTINF:10.480, 
20170215T224129-1-2.ts
#EXTINF:11.400, 
20170215T224129-1-3.ts
#EXTINF:11.120, 

 

20170215T224129-1-4.ts

。。。

#EXTINF:1.000000,
3RCP49g82011159.ts
#EXTINF:0.600000,
3RCP49g82011160.ts

#EXT-X-ENDLIST

看到ts结尾的文件,这才是视频真正的存放路径:

http://cdn.can.cibntv.net/12/201702161000/rexuechangan01/20170215T224129-1-0.ts 

这时候用浏览器下载就可以播放。不过这个播放不用我们去解析 android 4.0以后的videoView 就支持自动解析,并拼接播放。

安卓代码:

 

	Uri uri = Uri.parse("http://cdn.can.cibntv.net/12/201702161000/rexuechangan01/rexuechangan01.m3u8");
	video_view.setMediaController(new MediaController(this));
	video_view.setVideoURI(uri);
	video_view.requestFocus();
	ideo_view.start();
	这样就可以简单的播放M3u8格式的视频了。

 

下载到本地,可直接用视频软件打开:

python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频「建议收藏」

 

 

二、视频下载

可以用python脚本自动下载这些ts文件,但实际上有些网站的ts文件是用AES-128加密过的,所以需要解密才能播放。

加密过的视频在第二层m3u8中会有一个key文件链接:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-KEY:METHOD=AES-128,URI=”key.key”  #key密钥文件

需要去读取这个key文件,才能拿到解密密钥。

# -*- coding:utf-8 -*-  
import os
import sys
import requests
import datetime
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex

reload(sys)
sys.setdefaultencoding('utf-8')

def download(url):
    download_path = os.getcwd() + "\download"
    if not os.path.exists(download_path):
        os.mkdir(download_path)
        
    #新建日期文件夹
    download_path = os.path.join(download_path, datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
    #print download_path
    os.mkdir(download_path)
        
    all_content = requests.get(url).text  # 获取第一层M3U8文件内容
    if "#EXTM3U" not in all_content:
        raise BaseException("非M3U8的链接")

    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")

    unknow = True
    key = ""
    for index, line in enumerate(file_line): # 第二层
        if "#EXT-X-KEY" in line:  # 找解密Key
            method_pos = line.find("METHOD")
            comma_pos = line.find(",")
            method = line[method_pos:comma_pos].split('=')[1]
            print "Decode Method:", method
            
            uri_pos = line.find("URI")
            quotation_mark_pos = line.rfind('"')
            key_path = line[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 "key:" , key
            
        if "EXTINF" in line: # 找ts地址并下载
            unknow = False
            pd_url = url.rsplit("/", 1)[0] + "/" + file_line[index + 1] # 拼出ts片段的URL
            #print pd_url
            
            res = requests.get(pd_url)
            c_fule_name = file_line[index + 1].rsplit("/", 1)[-1]
            
            if len(key): # AES 解密
                cryptor = AES.new(key, AES.MODE_CBC, key)  
                with open(os.path.join(download_path, c_fule_name + ".mp4"), 'ab') as f:
                    f.write(cryptor.decrypt(res.content))
            else:
                with open(os.path.join(download_path, c_fule_name), 'ab') as f:
                    f.write(res.content)
                    f.flush()
    if unknow:
        raise BaseException("未找到对应的下载链接")
    else:
        print "下载完成"
    merge_file(download_path)

def merge_file(path):
    os.chdir(path)
    cmd = "copy /b * new.tmp"
    os.system(cmd)
    os.system('del /Q *.ts')
    os.system('del /Q *.mp4')
    os.rename("new.tmp", "new.mp4")
    
if __name__ == '__main__': 
    url = "http://cdn.can.cibntv.net/12/201702161000/rexuechangan01/rexuechangan01.m3u8" 
    download(_url)

 

 

 

三、关于解密报错:No module named Crypto.Cipher

在python 中使用AES算法时,会报告上述错误,原因是Crypto并非标准模块,需要自己单独安装。

 

from Crypto.Cipher import AES

第一种办法:pip install pycropt 如果报错,就选择第二种办法。

第二种办法:使用编译好的安装包。http://www.voidspace.org.uk/python/modules.shtml#pycrypto

 

装上不好使就换一个试试,安装上面2个都不好使,就安装低版本的(我本机安装上面2个都报错,安装下面的版本就可用了)

 

 

如果还是报错就到下面目录修改大小写:(我没遇到这个问题)

C:\Python27\Lib\site-packages\crypto 改成

 C:\Python27\Lib\site-packages\Crypto

 

四、合并文件

可以通过cmd命令的方式将所有的ts合并成一个文件:

copy /b d:\xxx\download_ts\*   d:\xxx\download_ts\new.mp4

直接调用merge_file即可,会删除临时文件

 

 

接受打赏:

python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频「建议收藏」

python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147426.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • simhash的应用范围_Simplorer

    simhash的应用范围_Simplorer目录0x01海量数据文本相似度解决方式SimHash+分词方法+基于内容推荐算法0x02海量simhash查询(1)抽屉原理(2)建立索引(3)判重(4)优化效果(5)权衡时间、空间(6)存储选型0x03比较相似度0x01海量数据文本相似度解决方式SimHash+分词方法+基于内容推荐算法原文链接:海量数据文本相似度解决方式SimHash+…

    2022年10月1日
    6
  • mysql如何查看用户及其权限「建议收藏」

    mysql如何查看用户及其权限「建议收藏」【1】查看mysql数据库中的所有用户SELECTDISTINCTCONCAT(‘User:”’,user,”’@”’,host,”’;’)ASqueryFROMmysql.user;【2】查看某个用户的权限showgrantsfor’nextcloud’@’%’;orselect*frommysql.userwhereuser=’r…

    2022年6月18日
    23
  • SQL Server 2008还原数据库时出现“备份集中的数据库备份与现有的数据库不同”的解决方法

    SQL Server 2008还原数据库时出现“备份集中的数据库备份与现有的数据库不同”的解决方法引言 nbsp nbsp nbsp nbsp 现在在做项目 由于每个人是分模块的 所以大家的测试数据都不同步 导致好多时候会因为别人填的数据不同而调半天的错 所以我还是自己还原一个数据库 自己填自己的数据吧 nbsp nbsp 报错 nbsp nbsp nbsp nbsp nbsp 之前还原过很多个数据库都没什么问题 这次也是按照之前的步骤 先建立了一个目标数据库 之后选择源文件进行还原 最后报了这么一个错 解决方法 nbsp 1 nbsp 首先我们

    2025年6月20日
    1
  • Python中“取整”的各种问题[通俗易懂]

    Python向上取整的算法一、初衷:  有时候我们分页展示数据的时候,需要计算页数。一般都是向上取整,例如counts=205pageCouts=20,pages=11页。一般的除法只是取整数部分,达不到要求。二、方法:1、通用除法:  UP(A/B)=int((A+B-1)/B)  取临界值,计算下A+B-1的范围就OK.2、Python除法:…

    2022年4月17日
    93
  • 2019 年 Redis面试题及答案[通俗易懂]

    2019 年 Redis面试题及答案

    2022年2月10日
    44
  • pytest 执行用例_测试用例执行结果有哪些

    pytest 执行用例_测试用例执行结果有哪些前言平常我们功能测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟,如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时,会需要协调多个测试资源来把任务分成两部分,于是执行时间

    2022年7月29日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号