日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

一文看懂,python抓取m3u8里ts加密视频及合成、多线程、写入的问题

發(fā)布時(shí)間:2024/3/26 python 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文看懂,python抓取m3u8里ts加密视频及合成、多线程、写入的问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

花了幾天時(shí)間搞m3u8里的ts視頻,還有多線程協(xié)程的處理問(wèn)題??戳舜罅康幕卮?#xff0c;發(fā)現(xiàn)大多數(shù)人講的都是個(gè)大概,具體的怎么用、什么原理沒(méi)講。今天就來(lái)帶大家講解怎么爬取m3u8里的加密ts視頻。

目標(biāo)網(wǎng)址我就不說(shuō)了,怕被和諧

以《叢林奇航DB》為例吧,首先找到目標(biāo)網(wǎng)址,再F12檢查,點(diǎn)擊網(wǎng)絡(luò),找到m3u8結(jié)尾的鏈接(找不到的話點(diǎn)擊刷新一下)。如下圖:

點(diǎn)擊預(yù)覽后會(huì)看到一連串的ts鏈接和以AES-128加密的key鏈接。如下圖:

如果鏈接不完整的話要手動(dòng)補(bǔ)全鏈接。

看到這里的話已經(jīng)所找到了視頻資源,接下來(lái)寫代碼爬取了。

首先導(dǎo)入庫(kù):

#!/usr/bin/env python3 # -*- coding: utf-8 -*-import time import os import requests import re import aiohttp import asyncio from Crypto.Cipher import AES

?crypto庫(kù)的安裝請(qǐng)前往crypto安裝 - 百度文庫(kù)自行了解。

再來(lái)說(shuō)說(shuō)AES的一個(gè)解密ts視頻原理,這里以爬取一部ts為例:

from Crypto.Cipher import AES# 提取key和ts的鏈接地址進(jìn)行訪問(wèn)與獲取文本 key_url = 'https://pps.shanshanku.com/20211127/g8V4A0hE/1000kb/hls/key.key' ts_url = 'https://pps.shanshanku.com/20211127/g8V4A0hE/1000kb/hls/z8WfPVdF.ts' key = requests.get(key_url).content ts = requests.get(ts_url).contentwith open('./date/video.ts', 'wb') as file:# 用Crupto庫(kù)里的AES進(jìn)行解密crypto = AES.new(key,AES.MODE_CBC, key)# 解密完成之后就可以寫入了file.write(crypto.decrypt(ts))file.close()

得到視頻。解密成功。沒(méi)解密直接寫入是無(wú)法播放的。

?解密原理已經(jīng)了解,接下來(lái)就是如何爬取多個(gè)ts視頻了。

下面來(lái)說(shuō)說(shuō)aiohttp庫(kù)和asyncio庫(kù)進(jìn)行協(xié)程的用法

# 第一步:得到一個(gè)url列表 urls = ['https://baidu.com','https://baidu.com','https://baidu.com'] # 第一步:用asyncio創(chuàng)建一個(gè)函數(shù)線程,用aiohttp來(lái)創(chuàng)建一個(gè)支持異步的訪問(wèn) async def get_status(url):# 類似session = aiohttp.ClientSession,with 前面要加async,獲取東西前用awaitasync with aiohttp.ClientSession() as session:async with await session.get(url) as response:# 如果是<str>類型的就用text().<byte>類型的就用read()text = await response.text()return text[:100]# 第三步:定義一個(gè)執(zhí)行模塊 if __name__ == '__main__':start = time.time()# 把第一步的列表放入函數(shù)塊里并導(dǎo)入到tasks列表tasks = []for url in urls:c = get_status(url)# 把函數(shù)塊放入線程task = asyncio.ensure_future(c)tasks.append(task)# 循環(huán)事件loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))# 循環(huán)完成后進(jìn)行關(guān)閉loop.close()print('總耗時(shí):', time.time()-start)

運(yùn)行后查看三個(gè)線程同時(shí)啟動(dòng)到完成后的總用時(shí):

我們可以看到,調(diào)用線程已經(jīng)成功,接下來(lái)就是怎么獲取和寫入了:下面對(duì)寫入進(jìn)行分析:

...... # 如果是<str>類型的就用text().<byte>類型的就用read()text = await response.text()return text[:100]# 這里只截取了一小部分 # 增加一個(gè)函數(shù)塊# 形參規(guī)定設(shè)為t,對(duì)線程運(yùn)行返回的結(jié)果進(jìn)行接收 def parsel(t):tlt = t.result()# 直接打印tlt返回的是一個(gè)元組類型,一個(gè)線程對(duì)應(yīng)一個(gè)元組,這里有三個(gè)線程print(tlt)# 如果元組里有多個(gè)數(shù)據(jù)時(shí),需要轉(zhuǎn)換為列表才能提取lis = list(tlt)with open('./date/http.txt', 'a') as file:# 對(duì)獲取的text[:100]進(jìn)行寫入file.write(str(tlt))file.close()......c = get_status(url)# 把函數(shù)塊放入線程task = asyncio.ensure_future(c)# 把parsel函數(shù)添加進(jìn)去。。。。。。。。。。。。。。。。。。。。task.add_done_callback(parsel)tasks.append(task)

?我們來(lái)看看打印效果和寫入效果:

?

到這一步,我們已經(jīng)知道怎么調(diào)用協(xié)程和解密包括寫入了

假設(shè)我們這一步已經(jīng)提取了所有的ts視頻文件

接下來(lái)就是對(duì)ts視頻進(jìn)行合并與刪除源文件了

合并有調(diào)用cmd和利用ffmpeg(需要安裝):

調(diào)用cmd和利用ffmpge進(jìn)行合成:

# 導(dǎo)入所需模塊 import os# 用ffmpeg進(jìn)行ts視頻合成 cmd = 'ffmpeg -f concat -safe 0 -i complex.txt(合成路徑與命名) -c copy output.mp4(輸出路徑與命名)'# 調(diào)用cmd os.system(cmd)

這樣我們就完成了ts視頻的合成。

接下來(lái)附上完整的代碼

#!/usr/bin/env python3 # -*- coding: utf-8 -*-# 導(dǎo)入所需的庫(kù) import time import os import requests import re import aiohttp import asyncio from Crypto.Cipher import AES# 創(chuàng)建一個(gè)URL列表 m3u8_URL = 'https://pps.sd-play.com/20220424/RN3p7Bj5/1200kb/hls/index.m3u8' resp = requests.get(url=m3u8_URL).text# 這里只提取300個(gè)ts視頻 rst = re.findall('https:(.*?).ts', resp)[:300] # name = re.findall('1200kb/hls/(.*?).ts',resp)[:5] # 給文件命名,用列表進(jìn)行封裝 tt = '{}' names = [tt.format(num) for num in range(10001, 10301)] # print(rst) print(names) # 把ts視頻封裝進(jìn)列表里 ts_list = [] for i in rst:ts_url = 'https:'+i+'.ts'ts_list.append(ts_url)# 限制最大協(xié)程數(shù)用Semaphore,時(shí)間原來(lái)這里不講了,不懂再問(wèn) concurrency = 15 semaphore = asyncio.Semaphore(concurrency)# 用asyncio和aiphttp結(jié)合創(chuàng)建線程 async def get_request(url, name):async with semaphore:# conn = aiohttp.TCPConnector(limit=15)async with aiohttp.ClientSession() as session:async with await session.get(url) as response:# 因?yàn)槭莃yte類型,所以用read()page_text = await response.read()return page_text, namedef parse(t):page_text = t.result()# 返回得到一個(gè)元組,轉(zhuǎn)換為列表,再對(duì)文件名和內(nèi)容進(jìn)行提取complex = list(page_text)na = complex[1]all = complex[0]# print(na)# print(all)# 用crypto里的AES進(jìn)行解密并保存key = b'b7d463938dcfabff'path = 'D:\\thead\\'with open(f'{path}{na}.ts', 'ab') as file:cryptor = AES.new(key, AES.MODE_CBC, key)file.write(cryptor.decrypt(all))print('下載完成')if __name__ == '__main__':start = time.time()# 定義列表,把元素放進(jìn)去并開啟協(xié)程tasks = []for url,name in zip(ts_list,names):c = get_request(url, name)task = asyncio.ensure_future(c)task.add_done_callback(parse)tasks.append(task)loop = asyncio.get_event_loop()try:loop.run_until_complete(asyncio.wait(tasks))except:loop.close()# 為方便ffmpeg合并,這里創(chuàng)建了一個(gè)txt文件列表里面包含每個(gè)ts的名稱。for j in range(10001, 10301):with open('D:\\thead\\list.txt', 'a') as file:file.write(f'file {j}.ts' + '\n')file.close()time.sleep(1)# 調(diào)用cmd并利用ffmpeg進(jìn)行合并cmd = f'ffmpeg -f concat -safe 0 -i D:\\thead\\list.txt -c copy D:\\thead\\theads\\new01.mp4'# cmd = f'copy/b D:\\thead\\* D:\\thead\\theads\\new01.ts'# 合并完成后再調(diào)用cmd進(jìn)行ts文件刪除os.system(cmd)delete = f'del D:\\thead\\*'os.system(delete)# 整個(gè)程序運(yùn)行所需的時(shí)間print('總用時(shí):', time.time()-start)

時(shí)間原因,還有些限制協(xié)程數(shù)就不多說(shuō)了,有問(wèn)題可以互相交流學(xué)習(xí)。

最后看一下效果:

好,大功告成!!!!?

總結(jié)

以上是生活随笔為你收集整理的一文看懂,python抓取m3u8里ts加密视频及合成、多线程、写入的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。