最近在搗鼓視頻轉碼,所謂好記性不如爛筆頭,索性把想到的知識點都記錄在案吧
現在大多數網站都使用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