日常中我們?cè)谝恍┚W(wǎng)站上看到有意思的電影或者視頻隘庄,想保存下來(lái),點(diǎn)擊下載卻發(fā)現(xiàn)這是一個(gè)以 .m3u8結(jié)尾的視頻鏈接癣亚。就算我們用手機(jī)下載下來(lái)丑掺,卻發(fā)現(xiàn)下載后得到的不是一個(gè)完整的視頻文件,而是一大堆ts結(jié)尾的視頻文件述雾,整個(gè)視頻被切割為一個(gè)個(gè)的幾秒的視頻文件街州。這里就使用python實(shí)現(xiàn)將視頻鏈接下載為一個(gè)完整的mp4視頻文件。
1.了解 m3u8 視頻鏈接
m3u8文件其實(shí)是 HTTP Live Streaming(縮寫(xiě)為 HLS)協(xié)議的部分內(nèi)容玻孟,而 HLS 是一個(gè)由蘋(píng)果公司提出的基于 HTTP 的 流媒體 網(wǎng)絡(luò)傳輸協(xié)議唆缴。
簡(jiǎn)而言之,HLS 是新一代流媒體傳輸協(xié)議取募,其基本實(shí)現(xiàn)原理為將一個(gè)大的媒體文件進(jìn)行分片琐谤,將該分片文件資源路徑記錄于 m3u8 文件(即 playlist)內(nèi),其中附帶一些額外描述用于提供給客戶(hù)端玩敏《芳桑客戶(hù)端依據(jù)該 m3u8 文件即可獲取對(duì)應(yīng)的媒體資源,進(jìn)行播放旺聚。
因此织阳,客戶(hù)端獲取 HLS 流文件,主要就是對(duì) m3u8 文件進(jìn)行解析操作砰粹。
2.解析 m3u8 文件
我們將獲取的視頻鏈接在瀏覽器上打開(kāi)唧躲,會(huì)得到一個(gè)以 .m3u8 為結(jié)尾的文件,使用記事本打開(kāi)
#EXTM3U
#EXT-X-TARGETDURATION:12
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:2,
http://play1.cp21.ott.cibntv.net/play.videocache.lecloud.com/ver_00_22_0_0_1_81028_0_0.ts
#EXTINF:3,
http://play1.cp21.ott.cibntv.net/play.videocache.lecloud.com/ver_00_22_1_1_1_113176_81028_0.ts
#EXTINF:5,
http://play1.cp21.ott.cibntv.net/play.videocache.lecloud.com/ver_00_22_2_2_1_248724_194204_0.ts
......
#EXT-X-ENDLIST
第一行 “#EXTM3U” 表明這個(gè)一個(gè) m3u8 格式的視頻文件碱璃,“#EXTINF”后面的一行鏈接便是每一個(gè)視頻流的文件地址弄痹。如果將鏈接輸入到瀏覽器中訪問(wèn),你將得到一個(gè)以 .ts 結(jié)尾的幾秒鐘視頻文件嵌器。這個(gè)文件中所有的鏈接全部請(qǐng)求得到的就是一個(gè)完整的視頻肛真。
有時(shí)候得到的 m3u8 文件不一樣,會(huì)有一行 “#EXT-X-KEY” 爽航,說(shuō)明這個(gè)視頻是經(jīng)過(guò)加密的蚓让,需要我們?nèi)ソ饷懿拍艿玫揭曨l,否則得到的視頻文件打開(kāi)就會(huì)報(bào)錯(cuò)讥珍。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.key"
#EXTINF:1.668333,
ir7QcW6705000.ts
#EXTINF:0.834167,
ir7QcW6705001.ts
#EXTINF:0.834167,
ir7QcW6705002.ts
這個(gè)文件中多了一行 “#EXT-X-KEY” 這個(gè)是向客戶(hù)端表明這個(gè)一個(gè)加密的視頻历极,加密方式為 AES-128 ,而加密文件是 key.key 衷佃,由于這個(gè)加密文件和視頻鏈接地址都無(wú)前綴趟卸,所以他們的鏈接前綴應(yīng)該是得到這個(gè)m3u8文件的鏈接,將末尾修改為key文件和視頻流名稱(chēng)就可得到完整的鏈接。
舉例說(shuō)明:
http://www.play1.com/index.m3u8 這個(gè)是m3u8文件鏈接锄列。
http://www.play1.com/key.key 這是加密文件的鏈接新蟆。
http://www.play1.com/ir7QcW6705000.ts 這是每一個(gè)視頻文件的鏈接
有時(shí)候我們得到的 m3u8 文件是這樣的
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=732000,RESOLUTION=720x480
hls/index.m3u8
我們將第一個(gè)鏈接后改為 http://www.play1.com/hls/index.m3u8 再次訪問(wèn)才能得到像上面格式的文件。這個(gè)只是將文件設(shè)置為二次訪問(wèn)獲取真實(shí)地址右蕊。
整個(gè)文件解析基本完成,現(xiàn)在進(jìn)行腳本編寫(xiě)吮螺,實(shí)現(xiàn)下載饶囚。
3.Python實(shí)現(xiàn)下載流程
這里實(shí)現(xiàn)加密視頻的下載
- 首先獲取 m3u8 文件并解析
import requests
import re
from Crypto.Cipher import AES
def m3u8(url):
header = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
# requests得到m3u8文件內(nèi)容
content = requests.get(url,headers=header).text
if "#EXTM3U" not in content:
print("這不是一個(gè)m3u8的視頻鏈接!")
return False
if "EXT-X-KEY" not in content:
print("沒(méi)有加密")
return False
# 使用re正則得到key和視頻地址
jiami=re.findall('#EXT-X-KEY:(.*)\n',content)
key=re.findall('URI="(.*)"',jiami[0])
#得到每一個(gè)ts視頻鏈接
tslist=re.findall('EXTINF:(.*),\n(.*)\n#',content)
newlist=[]
for i in tslist:
newlist.append(i[1])
# 先獲取URL/后的后綴鸠补,再替換為空
urlkey=url.split('/')[-1]
url2 = url.replace(urlkey, '') #這里為得到url地址的前面部分萝风,為后面key的鏈接和視頻鏈接拼接使用
#得到key的鏈接并請(qǐng)求得到加密的key值
keyurl=url2+key[0]
keycontent= requests.get(keyurl,headers=header).text
#得到每一個(gè)完整視頻的鏈接地址
tslisturl=[]
for i in newlist:
tsurl=url2+i
tslisturl.append(tsurl)
#得到解密方法,這里要導(dǎo)入第三方庫(kù) pycrypto
#這里有一個(gè)問(wèn)題紫岩,安裝pycrypto成功后规惰,導(dǎo)入from Crypto.Cipher import AES報(bào)錯(cuò)
#找到使用python環(huán)境的文件夾,在Lib文件夾下有一個(gè) site-packages 文件夾泉蝌,里面是我們環(huán)境安裝的包歇万。
#找到一個(gè)crypto文件夾,打開(kāi)可以看到 Cipher文件夾勋陪,此時(shí)我們將 crypto文件夾改為 Crypto 即可使用了
cryptor = AES.new(keycontent, AES.MODE_CBC, keycontent)
#for循環(huán)獲取視頻文件
for i in tslisturl:
res = requests.get(i, header)
#使用解密方法解密得到的視頻文件
cont=cryptor.decrypt(res.content)
#以追加的形式保存為mp4文件
with open('xx.mp4', 'ab+') as f:
f.write(cont)
return True
if __name__ == '__main__':
url = "https://xxxxxxx/hls/index.m3u8"
pd = m3u8(url)
if pd:
print('視頻下載完成贪磺!')
至此整個(gè)視頻文件下載腳本結(jié)束。啟動(dòng)腳本等待視頻下載完成诅愚,即可得到一個(gè)完整的 mp4 格式視頻文件寒锚。
后記
整個(gè)腳本實(shí)現(xiàn)過(guò)程比較粗糙。只是完成視頻的分析下載违孝。小伙伴們可以根據(jù)自己自行修改優(yōu)化刹前。這里也是參考不少大佬的博客技術(shù)文檔,站在大佬的肩上學(xué)習(xí)實(shí)現(xiàn)了這個(gè)腳本雌桑。感謝大佬們的技術(shù)博客分享喇喉,向大佬們致敬!