天天看點

python3下載下傳m3u8轉mp4_Python3爬蟲通過m3u8檔案下載下傳ts視訊 Python爬蟲

什麼是m3u8檔案?M3U8檔案是指UTF-8編碼格式的M3U檔案。

M3U檔案是記錄了一個索引純文字檔案,打開它時播放軟體并不是播放它,而是根據它的索引找到對應的音視訊檔案的網絡位址進行線上播放。

原視訊資料分割為很多個TS流,每個TS流的位址記錄在m3u8檔案清單中

比如我這裡有一個m3u8檔案,檔案内容如下:#EXTM3U

#EXT-X-VERSION:3

#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-ALLOW-CACHE:YES

#EXT-X-TARGETDURATION:15

#EXTINF:6.916667,

out000.ts

#EXTINF:10.416667,

out001.ts

#EXTINF:10.416667,

out002.ts

#EXTINF:1.375000,

out003.ts

#EXTINF:1.541667,

ts 檔案一般怎麼處理?

1 隻有m3u8檔案,需要下載下傳ts檔案

2 有ts檔案,但因為被加密無法播放,需要解碼

3 ts檔案能正常播放,但太多而小,需要合并

4 本篇文章處理第1和第2條内容,加密部分跳過。

上面我提供的ts檔案中并沒有加密,也就是沒有關鍵字key ,下載下傳ts檔案之後直接合并即可

ts檔案路徑擷取

由于上面的m3u8檔案中所有的ts檔案都是相對位址,是以需要依據上篇部落格中擷取到的連結{'url': 'https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/playlist.m3u8', 'ext': 'dplay', 'msg': 'ok', 'playertype': None}

其中前面的部分是ts的播放位址的字首位址# https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/out005.ts

import datetime,requests

# m3u8是本地的檔案路徑

def get_ts_urls(m3u8_path,base_url):

urls = []

with open(m3u8_path,"r") as file:

lines = file.readlines()

for line in lines:

if line.endswith(".ts\n"):

urls.append(base_url+line.strip("\n"))

return urls

ts檔案下載下傳

所有的路徑讀取完畢之後,需要對ts檔案進行下載下傳,檔案的下載下傳辦法很多def download(ts_urls,download_path):

for i in range(len(ts_urls)):

ts_url = ts_urls[i]

file_name = ts_url.split("/")[-1]

print("開始下載下傳 %s" %file_name)

start = datetime.datetime.now().replace(microsecond=0)

try:

response = requests.get(ts_url,stream=True,verify=False)

except Exception as e:

print("異常請求:%s"%e.args)

return

ts_path = download_path+"/{0}.ts".format(i)

with open(ts_path,"wb+") as file:

for chunk in response.iter_content(chunk_size=1024):

if chunk:

file.write(chunk)

end = datetime.datetime.now().replace(microsecond=0)

print("耗時:%s"%(end-start))

下載下傳過程顯示,表示下載下傳成功,剩下的就是拼網速的時候了。

python3下載下傳m3u8轉mp4_Python3爬蟲通過m3u8檔案下載下傳ts視訊 Python爬蟲

下載下傳完畢,是一大堆ts檔案,記住,隻要一個可以看,就可以合并了

python3下載下傳m3u8轉mp4_Python3爬蟲通過m3u8檔案下載下傳ts視訊 Python爬蟲

合并ts檔案     使用copy指令 如果不清楚,就去百度即可

在windows系統下面,直接可以使用:copy/b *.ts video.mp4  把所有ts檔案合成一個mp4格式檔案copy/b D:\newpython\doutu\sao\ts_files\*.ts d:\fnew.ts

代碼合并import os

from os import path

def file_walker(path):

file_list = []

for root, dirs, files in os.walk(path): # 生成器

for fn in files:

p = str(root+'/'+fn)

file_list.append(p)

print(file_list)

return file_list

def combine(ts_path, combine_path, file_name):

file_list = file_walker(ts_path)

file_path = combine_path + file_name + '.ts'

with open(file_path, 'wb+') as fw:

for i in range(len(file_list)):

fw.write(open(file_list[i], 'rb').read())

if __name__ == '__main__':

#urls = get_ts_urls("playlist.m3u8","https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/")

#download(urls,"./tsfiles")

combine("./ts_files","d:/ts","haha")

最終合并之後,形成一個ts檔案,當然你還可以用軟體把視訊轉換成mp4格式

也可以利用FFMPEG可以直接實作m3u8 轉MP4

備注部分

m3u8檔案中的 m3u8标簽與屬性說明#EXTM3U

每個M3U檔案第一行必須是這個tag,請标示作用

#EXT-X-VERSION:3

該屬性可以沒有

#EXT-X-MEDIA-SEQUENCE:140651513

每一個media URI在PlayList中隻有唯一的序号,相鄰之間序号+1,

一個media URI并不是必須要包含的,如果沒有,預設為0

#EXT-X-TARGETDURATION

指定最大的媒體段時間長(秒)。是以#EXTINF中指定的時間長度必須小于或是等于這

個最大值。這個tag在整個PlayList檔案中隻能出現一 次(在嵌套的情況下,一般有

真正ts url的m3u8才會出現該tag)

#EXT-X-PLAYLIST-TYPE

提供關于PlayList的可變性的資訊,這個對整個PlayList檔案有效,是可選的,格式

如下:#EXT-X-PLAYLIST-TYPE::如果是VOD,則伺服器不能改變PlayList 檔案;

如果是EVENT,則伺服器不能改變或是删除PlayList檔案中的任何部分,但是可以向該

檔案中增加新的一行内容。

#EXTINF

duration指定每個媒體段(ts)的持續時間(秒),僅對其後面的URI有效,title是

下載下傳資源的url

#EXT-X-KEY

表示怎麼對media segments進行解碼。其作用範圍是下次該tag出現前的所有media

URI,屬性為NONE 或者 AES-128。NONE表示 URI以及IV(Initialization

Vector)屬性必須不存在, AES-128(Advanced EncryptionStandard)表示URI

必須存在,IV可以不存在。

#EXT-X-PROGRAM-DATE-TIME

将一個絕對時間或是日期和一個媒體段中的第一個sample相關聯,隻對下一個meida

URI有效,格式如#EXT-X-PROGRAM-DATE-TIME:

For example: #EXT-X-PROGRAM-DATETIME:2010-02-19T14:54:23.031+08:00

#EXT-X-ALLOW-CACHE

是否允許做cache,這個可以在PlayList檔案中任意地方出現,并且最多出現一次,作

用效果是所有的媒體段。格式如下:#EXT-X-ALLOW-CACHE:

#EXT-X-ENDLIST

表示PlayList的末尾了,它可以在PlayList中任意位置出現,但是隻能出現一個,格

式如下:#EXT-X-ENDLIST