網上的TS流視頻文件下載,解密,合成一個文件的python方法(轉的別人大佬的,自己存一份~~)


  1 # -*- coding:utf-8 -*- 
  2 import os
  3 import sys
  4 import requests
  5 import datetime
  6 from Crypto.Cipher import AES
  7 from binascii import b2a_hex, a2b_hex
  8 
  9 # reload(sys)
 10 # sys.setdefaultencoding('utf-8')
 11 
 12 if 1:
 13     def debug(s):
 14         print(s)
 15 else:
 16     def debug(s):
 17         pass
 18 
 19 import importlib
 20 importlib.reload(sys)
 21 
 22 def download(url, savefile_path=''):
 23     # 創建download目錄
 24     download_path = os.getcwd() + "\download"
 25     if not os.path.exists(download_path):
 26         os.mkdir(download_path)
 27 
 28     #新建日期文件夾,如果沒有指定文件存儲位置,就用年月日創建文件夾,否則用指定的文件夾
 29     if not savefile_path:
 30         savefile_path = os.path.join(download_path, datetime.datetime.now().strftime('%Y%m%d'))
 31     else:
 32         savefile_path = os.path.join(download_path, savefile_path)
 33     print("savefile_path = " + savefile_path)
 34     if not os.path.exists(savefile_path):
 35         os.mkdir(savefile_path)
 36     
 37 
 38     #如果不存在first.m3u8,就重新獲取,並保存,否則證明之前已經獲取過,直接讀取就行了
 39     if not os.path.exists(os.path.join(download_path,'first.m3u8')):
 40         all_content = requests.get(url).text # 獲取第一層M3U8文件內容
 41         with open( os.path.join(download_path,'first.m3u8'),'w' ) as f:
 42             f.write(all_content)
 43         print("save first.m3u8")
 44     else:
 45         print("first.m3u8 is exist,just read it")
 46         all_content = open( os.path.join(download_path,'first.m3u8'),'r' ).read()
 47     
 48     # 不是M3U8文件,直接報錯退出
 49     if "#EXTM3U" not in all_content:
 50         raise BaseException("非M3U8的鏈接")
 51     # 
 52     if "EXT-X-STREAM-INF" in all_content: # 第一層
 53         # 從第一層中讀取所有的文件組成行列表 file_line
 54         print("we need to get the second line")
 55         file_line = all_content.split("\n")
 56         # 找到 .m3u8 ,拼出第二層的鏈接
 57         for line in file_line:
 58             if '.m3u8' in line:
 59                 url = url.rsplit("/", 1)[0] + "/" + line # 拼出第二層m3u8的URL
 60                 print("second line url = " + url)
 61                 # 沒存,就存一下,同first.m3u8的邏輯
 62                 if not os.path.exists(os.path.join(download_path,'second.m3u8')):
 63                     all_content = requests.get(url).text
 64                     with open( os.path.join(download_path,'second.m3u8'),'w' ) as f:
 65                         f.write(all_content)
 66                     print("second.m3u8 has been saved")
 67                 else:
 68                     all_content = open( os.path.join(download_path,'second.m3u8'),'r' ).read()
 69                 break
 70     # 到此為止,all_content里面的內容已經更新成了包含所有文件名的最終文件
 71     #           url 更新成了下載最終m3u8的URL
 72     
 73     # 把里面的元素分割出來
 74     file_line = all_content.split("\n")
 75 
 76     unknow = True
 77     key = ""
 78     
 79     for line in file_line:
 80         # 先找到解密key
 81         if "#EXT-X-KEY" in line: # 找解密Key
 82             method_pos = line.find("METHOD")
 83             comma_pos = line.find(",")
 84             method = line[method_pos:comma_pos].split('=')[1]
 85             print("Decode Method:", method)
 86          
 87             uri_pos = line.find("URI")
 88             quotation_mark_pos = line.rfind('"')
 89             key_path = line[uri_pos:quotation_mark_pos].split('"')[1]
 90          
 91             key_url = url.rsplit("/", 1)[0] + "/" + key_path # 拼出key解密密鑰URL
 92             res = requests.get(key_url)
 93             key = res.content
 94             
 95             with open( os.path.join(download_path,'key.key'),'wb' ) as f:
 96                 f.write(key)
 97 
 98             cryptor = AES.new(key, AES.MODE_CBC, key) 
 99             print( "key:" , key)
100             break
101             print("you cann't see me")
102     # 再進行下載和解密
103     for index, line in enumerate(file_line):    # 第二層
104         if "EXTINF" in line: # 找ts地址並下載
105             unknow = False
106             pd_url = url.rsplit("/", 1)[0] + "/" + file_line[index + 1] # 拼出ts片段的URL
107          
108             c_fule_name = file_line[index + 1].rsplit("/", 1)[-1]
109             # 如果文件已經存在,就下一個
110             if os.path.exists( os.path.join(savefile_path, c_fule_name) ):
111                 print("file %s exist, next" % c_fule_name)
112                 continue
113             # 網絡不好的時候會失敗,所以重復3次
114             for i in range(3):
115                 # 獲取視頻內容
116                 print("get video " + datetime.datetime.now().strftime('%H:%M:%S'))
117                 res = requests.get(pd_url)
118                 try:
119                     if len(key): # AES 解密,有key就是需要解密
120                         with open(os.path.join(savefile_path, c_fule_name), 'ab') as f:
121                             f.write(cryptor.decrypt(res.content))
122                         print(c_fule_name + " success")
123                         break
124                     else:  # 沒有key就不需要解密了,直接保存文件就行了
125                         with open(os.path.join(savefile_path, c_fule_name), 'ab') as f:
126                             f.write(res.content)
127                             f.flush()
128                         print(c_fule_name + " success")
129                         break
130                 except:  # 網絡不好導致下載失敗,清除文件
131                     print( str(i+1) + " download error, file: " + c_fule_name)
132                     os.remove(os.path.join(savefile_path, c_fule_name))
133             else:  # 下載失敗,先跳過這個文件,后面重新執行的時候在重新下載
134                 print("download file has failed 3 times, jump it")
135                 #exit()
136 
137     if unknow:
138         raise BaseException("未找到對應的下載鏈接")
139     else:
140         print( "下載完成")
141         # merge_file(savefile_path)
142 
143 def merge_file(path):
144     os.chdir(path)
145     cmd = "copy /b * new.ts"
146     #os.system(cmd)
147     #os.system('del /Q *.ts')
148     #os.system('del /Q *.mp4')
149     #os.rename("new.tmp", "new.mp4")
150  
151 if __name__ == '__main__':
152     url = input("please input the url of index.m3u8 file:\n")
153     savefile_path = input("give me a dir name to save all the video:\n(or you can just press Enter and I will create one for you)\n")
154     # url = r''
155     # savefile_path = r''
156     download(url,savefile_path)

 


免責聲明!

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



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