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,合并成整体视频「建议收藏」

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • QQ开心农场外挂软件设计思路「建议收藏」

    QQ开心农场外挂软件设计思路「建议收藏」今天玩了一下QQ的开心农场,我有一堆朋友在玩。每次去偷别人的东西时,都要一个一个地点选,看看是否有可摘的东西。然后还要一个个地点摘取,这样才算偷到,感觉好像有点太麻烦了。有时候朋友的东西可摘了,但是我没时间去看(总不能每XX分钟查一次,每次查全部的朋友的吧。。@@,那样会累死。。)然后我就想,如果有一软件,可以自动去自己的好友的地里偷东西。每隔十分钟查一次,如果好友的地里有东西可以摘,就把它…

  • 回文字符串判断python实现

    回文字符串判断python实现一:什么是回文字符串例如:abccba,qwerewq等,奇数偶数个都可以;二:实现方法1):使用切片defis_palindromic(num):str_len=len(num)index=str_len//2str1=num[:index]str2=num[index:][::-1]ifstr1==s…

  • 图片上传插件upload_flash控件上传照片

    图片上传插件upload_flash控件上传照片protectedvoidButton1_Click(objectsender,EventArgse){if(FileUpload1.HasFile){stringfileContentType=FileUpload1.PostedFile.ContentType;…

  • 三星一万多的翻盖手机叫什么_华为nex双屏

    三星一万多的翻盖手机叫什么_华为nex双屏三星用翻盖机怀念过去。哪怕国内市场份额不足1%,三星也要在新品发布会上用“逼格”力压群芳。11月9日,刚在旧金山用折叠手机吸引了不少目光的三星,在无锡和中国联通发布了针对成功商务人士的新机——三星W2019。开场,三星就扔出了钢琴演奏家马克西姆、男高音歌唱家戴玉强两张“格调十足”的王牌。场内“野蜂”与美声齐飞,场外美女与骏马亮相。…

  • bat倒计时代码

    bat倒计时相信大家都想要代码吧,下面是代码。@echooffseta=(这里是几分不支持10分)setb=(这里是几秒):dao1set/ab=b-1ping-n2-w500127.1>nulclsecho倒计时:%a%分%b%秒if%b%==0(set/aa=a-1)else(gotodao1)if%a%==-1(goto…

  • 搭建smtp邮件服务器_smtp服务器怎么填

    搭建smtp邮件服务器_smtp服务器怎么填4.“传递”选项卡在“默认SMTP虚拟服务器属性”对话框中点击“传递”选项卡,如图所示。该选项卡用来设定邮件一次发送不成功时,SMTP服务器如何处理这些邮件。在大多数情况下,每个虚拟服务器都尽量在消息一抵达消息队列后就进行发送;可是,如果下一个中继段的服务器发生了某个临时性的问题,或者网络中发生了某种通信故障,那么虚拟服务器就会采取适当的措施,例如对消息进行排队,准备再次重试,或者变更消息路由。如…

发表回复

您的电子邮箱地址不会被公开。

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