Python爬蟲入門教程 51-100 Python3爬蟲通過m3u8文件下載ts視頻-Python爬蟲6操作


什么是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,
out004.ts
#EXTINF:7.666667,
out005.ts
#EXTINF:10.416667,

ts 文件一般怎么處理

  • 只有m3u8文件,需要下載ts文件
  • 有ts文件,但因為被加密無法播放,需要解碼
  • ts文件能正常播放,但太多而小,需要合並

本篇文章處理第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
import 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))

下載過程顯示,表示下載成功,剩下的就是拼網速的時候了。
在這里插入圖片描述
下載完畢,是一大堆ts文件,記住,只要一個可以看,就可以合並了
在這里插入圖片描述

合並ts文件

使用copy命令 如果不清楚,就去百度即可

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

愉快的下載下來看VIP視頻吧
在這里插入圖片描述

備注部分

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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM