import json import requests import os import subprocess import typing import threading import time class song: def __init__(self, json_song) -> None: self.__url = json_song["url"] self.__artist = json_song["artist"] self.__title = json_song["title"] @property def url(self) -> str: return self.__url @property def artist(self) -> str: return self.__artist @property def title(self) -> str: return self.__title def seg_finder(mlst: typing.List[str]): for i in mlst: if i[:3] == "seg": yield i def the_fetcher(m_subj: song, number): global counter global thread_count start = time.time() root_url = m_subj.url.split("index.m3u8")[0] inc_name = root_url.split("/")[-2] os.mkdir("music/" + inc_name) f = open("music/" + inc_name + "/" + "index.m3u8", "wb") m3u8 = requests.get(m_subj.url).content f.write(m3u8) f.close() m3u8 = list(seg_finder(str(m3u8).split("\\n")[:-1])) m3u8.sort() for i in m3u8: f = open("music/" + inc_name + "/" + i, "wb") f.write(requests.get(root_url + i).content) f.close() prc = subprocess.Popen( f'ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -allowed_extensions ALL -i music/{inc_name}/index.m3u8 -metadata title="{m_subj.title}" -metadata artist="{m_subj.artist}" -metadata track={number} music/"{m_subj.title} - {m_subj.artist}".mp3 &> /dev/null && rm -r music/{inc_name}', shell=True, ) prc.wait() print( f"Process number {number} ({m_subj.title} - {m_subj.artist}) is done in {time.time() - start}s" ) counter -= 1 locker.acquire() thread_count -= 1 locker.release() inp = open("music_info.json", "r+") m_seq = [song(i) for i in json.load(inp)] m_seq.reverse() counter = len(m_seq) endway = counter locker = threading.Lock() thread_count = 0 glb_start = time.time() i = 0 while i < endway: locker.acquire() if thread_count >= 8: locker.release() else: i += 1 thread_count += 1 locker.release() thread = threading.Thread(target=the_fetcher, args=(m_seq.pop(), i)) thread.start() while counter != 0: pass print(f"Program is done in {(time.time() - glb_start)}s")