python 玩轉m3u8視頻


最近在搗鼓視頻轉碼,所謂好記性不如爛筆頭,索性把想到的知識點都記錄在案吧

現在大多數網站都使用m3u8格式的視頻文件,一是體積小,傳輸快;二是可以切片,提高用戶體驗。

好了,廢話不多說,開始今天的主題:

假如我們在網站上看到一個好的視頻,我們想下載下來,怎么辦??那這篇文章可以幫助到你(不過你要會使用pthon啊,騷年~~)

先放一張流程圖:

 

具體就分這4步,概括一下就是在瀏覽器中找到這個m3u8文件,下載里面所有的ts文件,最后將所有的ts文件合並為mp4視頻。

完整上碼

 1 import re
 2 import requests, os
 3 project_path = os.path.abspath(os.path.dirname(__file__))
 4 video_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'video'))
 5 
 6 
 7 class VideoSynthesis:
 8     def __init__(self):
 9         self.header = {
10             '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'
11         }
12         self.m3u8_link = 'https://v.pinimg.com/videos/v2/hls/49/3e/6b/493e6bb3f832caf2bef872d648698ff4_hls480w.m3u8'
13         self.base_url = 'https://v.pinimg.com/videos/v2/hls/49/3e/6b/'
14 
15     def get_m3u8_link(self):
16         # 下載m3u8視頻
17         m3u8_response = requests.get(url=self.m3u8_link, headers=self.header, verify=False)
18         print(m3u8_response.text)
19         return m3u8_response
20 
21     def handle_m3u8_response(self, m3u8_response):
22         # 處理m3u8響應
23         ts_filename = re.findall('.*?EXTINF:.*?,\n(.*?)\n', m3u8_response.replace(' ', '').replace(r'\n', ''))
24         print(f'tslist: {ts_filename}')
25         ts_link_list = []
26         for item in ts_filename:
27             result_url = self.base_url + item
28             ts_link_list.append(result_url)
29         print(f'ts_link_list: {ts_link_list}')
30         return ts_link_list, ts_filename
31 
32     def download_ts_video(self, ts_url_list, ts_filename):
33         # 通過ts鏈接下載ts文件
34         for i in range(len(ts_url_list)):
35             ts_url = ts_url_list[i]
36             ts_name = ts_filename[i]
37             try:
38                 response = requests.get(ts_url, stream=True, verify=False)
39             except Exception as e:
40                 print("異常請求:%s" % e.args)
41                 return
42 
43             # 在當前目錄下創建個video文件夾
44             ts_path = project_path + r"\video\{}".format(ts_name)
45             with open(ts_path, "wb+") as file:
46                 for chunk in response.iter_content(chunk_size=1024):
47                     if chunk:
48                         file.write(chunk)
49         print("TS文件下載完畢!!")
50 
51     def heBingTsVideo(self):
52         # 視頻合成
53         hebing_path = video_path + r"\m3u8_video.mp4"
54         print(hebing_path)
55         all_ts = os.listdir(video_path)
56         with open(hebing_path, 'wb+') as f:
57             for i in range(len(all_ts)):
58                 ts_video_path = os.path.join(video_path, all_ts[i])
59                 f.write(open(ts_video_path, 'rb').read())
60         print("合並完成!!")
61 
62     def run(self):
63         m3u8_response = self.get_m3u8_link()
64         ts_link_list, ts_filename = self.handle_m3u8_response(m3u8_response)
65         
66         # ts_link_list = ['https://v.pinimg.com/videos/v2/hls/49/3e/6b/493e6bb3f832caf2bef872d648698ff4_hls480w00000.ts', 'https://v.pinimg.com/videos/v2/hls/49/3e/6b/493e6bb3f832caf2bef872d648698ff4_hls480w00001.ts', 'https://v.pinimg.com/videos/v2/hls/49/3e/6b/493e6bb3f832caf2bef872d648698ff4_hls480w00002.ts', 'https://v.pinimg.com/videos/v2/hls/49/3e/6b/493e6bb3f832caf2bef872d648698ff4_hls480w00003.ts']
67         # ts_filename = ['493e6bb3f832caf2bef872d648698ff4_hls480w00000.ts', '493e6bb3f832caf2bef872d648698ff4_hls480w00001.ts' ,'493e6bb3f832caf2bef872d648698ff4_hls480w00002.ts', '493e6bb3f832caf2bef872d648698ff4_hls480w00003.ts']
68         
69         self.download_ts_video(ts_link_list, ts_filename)
70         self.heBingTsVideo()
71 
72 
73 if __name__ == '__main__':
74     video_synthesis = VideoSynthesis()
75     video_synthesis.run()

 

視頻下載完以后,可能還會遇到壓縮,合並問題,那這時候就要用到ffmpeg 這個神器了,直接編寫一個腳本就完事了~

 

 1 # coding=utf-8
 2 
 3 import os
 4 
 5 NEW_RESOLUTION = "640x480"  # 目標分辨率,常量
 6 NEW_FPS = 12  # 目標幀率,常量
 7 
 8 curpath = os.getcwd()  # 獲取當前路徑
 9 input_dir = os.path.join(curpath, "Input_Video")
10 output_dir = os.path.join(curpath, "Output_Video")
11 input_video_list = os.listdir(input_dir)  # 獲取視頻列表
12 
13 # 如果沒有Output_Video這個文件夾,則創建這個文件夾
14 if not os.path.exists(output_dir):
15     os.mkdir(output_dir)
16 
17 # 開始批量二次編碼壓縮視頻轉碼
18 for each_video in input_video_list:
19     video_name, _ = os.path.splitext(each_video)  # _是沒意義,就只是一個無用代號,占個坑而已
20     ffmpeg_command = ("ffmpeg -i %s%s%s -s %s -r %s -y %s%s%s_c.mp4" % (
21         input_dir, os.sep, each_video, NEW_RESOLUTION, NEW_FPS, output_dir, os.sep, video_name))
22     print(ffmpeg_command)
23     os.system(ffmpeg_command)
24 
25 os.system("pause")

注意:這里調用的是系統指令,所以務必使你的ffmpeg.exe執行程序能夠被訪問到,放到系統全局變量路徑下面即可。

 

視頻合並

1 ffmpeg -f concat -i filelist.txt -c copy output.mp4
filelist.txt為ffmpeg同級目錄下新建記事本,名字隨意,而里面的內容長這個樣子
file 's1-1.mp4'
file 's1-2.mp4'
file 's1-3.mp4'

注意,如果用這種方式,那么這3個文件也必須存放在同級目錄下。如果想使用全路徑的形式,比如:file D:\s1\2.mp4'

則應使用下面這條命令

ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4  -- -safe 0 授權進入

 

 

參考文章  https://blog.csdn.net/weixin_38640052/article/details/119680697

      https://blog.csdn.net/human_soul/article/details/103263573

      https://www.cnblogs.com/zipython/p/12920095.html

      https://jingyan.baidu.com/article/2a138328517dce464b134f24.html

      https://blog.csdn.net/winniezhang/article/details/89260841

 

 

 


免責聲明!

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



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