Python 下載m3u8格式的視頻

日常中我們?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ù)博客分享喇喉,向大佬們致敬!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末筹燕,一起剝皮案震驚了整個(gè)濱河市轧飞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撒踪,老刑警劉巖过咬,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異制妄,居然都是意外死亡掸绞,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)衔掸,“玉大人烫幕,你說(shuō)我怎么就攤上這事〕ㄓ常” “怎么了较曼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)振愿。 經(jīng)常有香客問(wèn)我捷犹,道長(zhǎng),這世上最難降的妖魔是什么冕末? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任萍歉,我火速辦了婚禮,結(jié)果婚禮上档桃,老公的妹妹穿的比我還像新娘枪孩。我一直安慰自己,他們只是感情好藻肄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布蔑舞。 她就那樣靜靜地躺著,像睡著了一般嘹屯。 火紅的嫁衣襯著肌膚如雪斗幼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天抚垄,我揣著相機(jī)與錄音蜕窿,去河邊找鬼。 笑死呆馁,一個(gè)胖子當(dāng)著我的面吹牛桐经,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浙滤,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼阴挣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了纺腊?” 一聲冷哼從身側(cè)響起畔咧,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揖膜,沒(méi)想到半個(gè)月后誓沸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壹粟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年拜隧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洪添,死狀恐怖垦页,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情干奢,我是刑警寧澤痊焊,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站忿峻,受9級(jí)特大地震影響宋光,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炭菌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逛漫。 院中可真熱鬧黑低,春花似錦、人聲如沸酌毡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)枷踏。三九已至菩暗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旭蠕,已是汗流浹背停团。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掏熬,地道東北人佑稠。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像旗芬,于是被迫代替她去往敵國(guó)和親舌胶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容