Spaces:
Running
Running
from tempfile import mkdtemp | |
from yt_dlp import YoutubeDL | |
import yt_dlp | |
from yt_dlp.postprocessor import PostProcessor | |
class FilenameCollectorPP(PostProcessor): | |
def __init__(self): | |
super(FilenameCollectorPP, self).__init__(None) | |
self.filenames = [] | |
def run(self, information): | |
self.filenames.append(information["filepath"]) | |
return [], information | |
def download_url(url: str, maxDuration: int = None): | |
try: | |
return _perform_download(url, maxDuration=maxDuration) | |
except yt_dlp.utils.DownloadError as e: | |
# In case of an OS error, try again with a different output template | |
if e.msg and e.msg.find("[Errno 36] File name too long") >= 0: | |
return _perform_download(url, maxDuration=maxDuration, outputTemplate="%(title).10s %(id)s.%(ext)s") | |
pass | |
def _perform_download(url: str, maxDuration: int = None, outputTemplate: str = None): | |
destinationDirectory = mkdtemp() | |
ydl_opts = { | |
"format": "bestaudio/best", | |
'playlist_items': '1', | |
'paths': { | |
'home': destinationDirectory | |
} | |
} | |
# Add output template if specified | |
if outputTemplate: | |
ydl_opts['outtmpl'] = outputTemplate | |
filename_collector = FilenameCollectorPP() | |
with YoutubeDL(ydl_opts) as ydl: | |
if maxDuration and maxDuration > 0: | |
info = ydl.extract_info(url, download=False) | |
duration = info['duration'] | |
if duration >= maxDuration: | |
raise ExceededMaximumDuration(videoDuration=duration, maxDuration=maxDuration, message="Video is too long") | |
ydl.add_post_processor(filename_collector) | |
ydl.download([url]) | |
if len(filename_collector.filenames) <= 0: | |
raise Exception("Cannot download " + url) | |
result = filename_collector.filenames[0] | |
print("Downloaded " + result) | |
return result | |
class ExceededMaximumDuration(Exception): | |
def __init__(self, videoDuration, maxDuration, message): | |
self.videoDuration = videoDuration | |
self.maxDuration = maxDuration | |
super().__init__(message) |