[Part 2] HLS - hls everywhere - Download by python3 code how?

Code python3 (file :"hls_me.py")







import sys
import threading
import queue
import m3u8
import requests
import shutil
import tempfile
import os
import posixpath
import urllib.parse
import re
import time
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import hashlib
print(hashlib.md5("whatever your string is".encode('utf-8')).hexdigest())

UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
UserAgent2= "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"

def is_url(uri):
 return re.match(r'https?://', uri) is not None

# c = threading.Condition()
countIdm= 0
firtRun = 0
# data_lock = threading.Lock()
class SegmentDownloadThread(threading.Thread):
 def __init__(self, downloadqueue, location, total, soLuong, refUrl):
  threading.Thread.__init__(self)
  self.downloadQueue = downloadqueue
  self.location = location
  self.total = total
  self.soLuong= soLuong
  self.refUrl= refUrl
 
 def run(self):
  global countIdm,firtRun
  while True:
   # print(countIdm)
   # with data_lock:
   #  countIdm+=1
   if(countIdm>= self.soLuong):
    time.sleep(0.7)
    continue
   # if(firtRun!=0):
   #  continue
   firtRun= 1
   countIdm+=1

   item = self.downloadQueue.get()
   if item is None:
    countIdm-=1
    return
   print('download thread: ', countIdm)
   self.execute(item)

   # with data_lock:
   #  countIdm-=1
   countIdm-=1
   self.downloadQueue.task_done()
 
 def execute(self, item):
  if item[1] and not is_url(item[2]):
   url = item[1] + "/" + item[2]
  else:
   url = item[2]
   item[2] = os.path.basename(urllib.parse.urlparse(url).path)
   
  if item[3]:
   backend = default_backend()
   r = requests.get(item[3].uri)
   key = r.content
   cipher = Cipher(algorithms.AES(key), modes.CBC(bytes.fromhex(item[3].iv[2:])), backend=backend)
   decryptor = cipher.decryptor()
  def lol(int_try, userAgent):
   if(int_try> 3):
    print('# requests.exceptions.RequestException #')
   else:
    try:
     #r = requests.get(url, stream=True, timeout=10)
     print(url)
     r= requests.get(url,  headers={"User-Agent": userAgent, 'Referer': self.refUrl}, stream=True, timeout=10)
     tenfile_fix2= item[4]
     # with open(os.path.join(self.location, item[2]), 'wb') as f:
     with open(os.path.join(self.location, tenfile_fix2), 'wb') as f:
      for chunk in r.iter_content(chunk_size=1024):
       if chunk:
        if item[3]:
         f.write(decryptor.update(chunk))
        else:
         f.write(chunk)
    except requests.exceptions.RequestException as e:
     if('Read timed out' in str(e) or 'ConnectTimeoutError' in str(e)):
      print("> ", int_try, ': ', url)
      time.sleep(3* (int_try+1)) # sleep 3s
      lol(int_try+1, UserAgent2)
    except Exception as g:
     print(g)
  lol(0, UserAgent)

def concatenate_files(filelist, source, destination, name):
 print(os.path.join(destination, name))
 with open(os.path.join(destination, name), 'ab') as outfile:
  for file in filelist:
   print(os.path.join(source, file))
   # shutil.copy2(os.path.join(source, file), 'C:/Users/Admin/Documents/PyProject/hlsMe/temp')
   if(os.path.isfile( os.path.join(source, file) )):
    print('join the file: ', file)
    with open(os.path.join(source, file), 'rb') as readfile:
     shutil.copyfileobj(readfile, outfile)
 outfile.close()
 #sys.exit(0)

def m3u8_load(uri):
 r = requests.get(uri)
 m3u8_obj = m3u8.M3U8(r.text)
 return m3u8_obj
def m3u8_load_file(uri):
 file1 = open(uri,"r")
 m3u8_obj = m3u8.M3U8(file1.read())
 file1.close()
 return m3u8_obj

def hls_fetch(playlist_location, storage_location, name, soLuong, refUrl, prefixURL):
 oldSegmentList = list()
 print("Downloading %s" % name)
 while True:
  print('...')
  download_queue = queue.Queue()
  tsSliceList = list()
  
  with tempfile.TemporaryDirectory() as download_location:
   if(is_url(playlist_location)):
    playlist = m3u8_load(playlist_location)
   else:
    playlist = m3u8_load_file(playlist_location)
    playlist_location= prefixURL
   print(playlist)
   parsed_url = urllib.parse.urlparse(playlist_location)
   prefix = parsed_url.scheme + '://' + parsed_url.netloc
   base_path = posixpath.normpath(parsed_url.path + '/..')
   base_uri = urllib.parse.urljoin(prefix, base_path)
   pool = list()
   total = 0
   
   for number, file in enumerate(playlist.segments):
    if not is_url(file.uri):
     playlist.base_uri = base_uri
    tenfile_fix2= hashlib.md5(file.uri.encode('utf-8')).hexdigest()
    if tenfile_fix2 not in oldSegmentList:
     total += 1
     # print('Downing, ',tenfile_fix2)
     oldSegmentList.append(tenfile_fix2)
     tsSliceList.append(tenfile_fix2)
     download_queue.put([number, playlist.base_uri, file.uri, file.key,tenfile_fix2]) 
   if total == 0:
    print('Please choose one in playlists:')
    # print(playlist.playlists[0].uri)
    for playlist in playlist.playlists:
     print("resolution {0}: {1}".format(playlist.stream_info.resolution, playlist.uri))
    break
   # for debug
   #total = 10
   for i in range(total):
    thread = SegmentDownloadThread(download_queue, download_location, total, soLuong, refUrl)
    thread.daemon = True
    thread.start()
    pool.append(thread)
   download_queue.join()
   
   for i in range(total):
    download_queue.put(None)
   
   for thread in pool:
    thread.join()
   print('Start joining the file')
   concatenate_files(tsSliceList, download_location, storage_location, name)
   tsSliceList.clear()
   break


Wait part 3...

Comments