This commit is contained in:
b-hayes 2025-08-23 14:39:06 +02:00 committed by GitHub
commit cf4b478ab1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 5 deletions

9
.gitignore vendored
View file

@ -14,6 +14,7 @@ speed-measure-plugin*.json
# IDEs and editors # IDEs and editors
/ui/.idea /ui/.idea
.idea/
.project .project
.classpath .classpath
.c9/ .c9/
@ -44,6 +45,12 @@ testem.log
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# Python
__pycache__ __pycache__
.venv .venv
# Environment files
.env
# Downloads directory
downloads/

View file

@ -28,7 +28,9 @@ def get_format(format: str, quality: str) -> str:
if format in AUDIO_FORMATS: if format in AUDIO_FORMATS:
# Audio quality needs to be set post-download, set in opts # Audio quality needs to be set post-download, set in opts
return f"bestaudio[ext={format}]/bestaudio/best" # Use a more robust format string that ensures audio-only download
# and has better fallbacks
return f"bestaudio[ext={format}]/bestaudio[ext=m4a]/bestaudio[ext=mp3]/bestaudio/best[ext!=webm]/best[ext!=webm]"
if format in ("mp4", "any"): if format in ("mp4", "any"):
if quality == "audio": if quality == "audio":

View file

@ -97,7 +97,7 @@ class Download:
'outtmpl': { "default": self.output_template, "chapter": self.output_template_chapter }, 'outtmpl': { "default": self.output_template, "chapter": self.output_template_chapter },
'format': self.format, 'format': self.format,
'socket_timeout': 30, 'socket_timeout': 30,
'ignore_no_formats_error': True, 'ignore_no_formats_error': False, # Changed to False to get better error messages
'progress_hooks': [put_status], 'progress_hooks': [put_status],
'postprocessor_hooks': [put_status_postprocessor], 'postprocessor_hooks': [put_status_postprocessor],
**self.ytdl_opts, **self.ytdl_opts,
@ -343,6 +343,13 @@ class DownloadQueue:
'ignore_no_formats_error': True, 'ignore_no_formats_error': True,
'noplaylist': playlist_strict_mode, 'noplaylist': playlist_strict_mode,
'paths': {"home": self.config.DOWNLOAD_DIR, "temp": self.config.TEMP_DIR}, 'paths': {"home": self.config.DOWNLOAD_DIR, "temp": self.config.TEMP_DIR},
'cookiefile': None, # Allow cookie usage if available
'age_limit': None, # Don't restrict by age
'geo_bypass': True, # Attempt to bypass geographic restrictions
'geo_bypass_country': None, # Let yt-dlp choose the best bypass method
'extractor_retries': 3, # Retry extraction up to 3 times
'youtube_include_dash_manifest': True, # Include DASH formats for YouTube Music
'youtube_skip_dash_manifest': False, # Don't skip DASH manifest
**self.config.YTDL_OPTIONS, **self.config.YTDL_OPTIONS,
**({'impersonate': yt_dlp.networking.impersonate.ImpersonateTarget.from_str(self.config.YTDL_OPTIONS['impersonate'])} if 'impersonate' in self.config.YTDL_OPTIONS else {}), **({'impersonate': yt_dlp.networking.impersonate.ImpersonateTarget.from_str(self.config.YTDL_OPTIONS['impersonate'])} if 'impersonate' in self.config.YTDL_OPTIONS else {}),
}).extract_info(url, download=False) }).extract_info(url, download=False)
@ -420,7 +427,6 @@ class DownloadQueue:
ytdl_options = dict(self.config.YTDL_OPTIONS) ytdl_options = dict(self.config.YTDL_OPTIONS)
if playlist_item_limit > 0: if playlist_item_limit > 0:
log.info(f'playlist limit is set. Processing only first {playlist_item_limit} entries') log.info(f'playlist limit is set. Processing only first {playlist_item_limit} entries')
ytdl_options['playlistend'] = playlist_item_limit
if auto_start is True: if auto_start is True:
download = Download(dldirectory, self.config.TEMP_DIR, output, output_chapter, quality, format, ytdl_options, dl) download = Download(dldirectory, self.config.TEMP_DIR, output, output_chapter, quality, format, ytdl_options, dl)
self.queue.put(download) self.queue.put(download)

27
docker-compose-dev.yml Normal file
View file

@ -0,0 +1,27 @@
# MeTube - Self-hosted YouTube downloader with web UI
# This setup allows you to modify the code and see changes reflected in the running container
services:
metube:
build: .
container_name: MeTube
restart: unless-stopped
ports:
- "8081:8081"
environment:
# Tells MeTube to use separate directories for video and audio downloads
- DOWNLOAD_DIR=/downloads/video
- AUDIO_DOWNLOAD_DIR=/downloads/audio
# Sensible filename templates for downloads
- OUTPUT_TEMPLATE=%(artist,uploader)s/%(artist,uploader)s - %(title)s%(genre& [%s]|)s (%(release_date>%Y-%m-%d,upload_date>%Y-%m-%d)s).%(ext)s
- OUTPUT_TEMPLATE_PLAYLIST=%(playlist_title)s/%(artist,uploader)s - %(title)s%(genre& [%s]|)s (%(release_date>%Y-%m-%d,upload_date>%Y-%m-%d)s).%(ext)s
# Development environment
- PYTHONUNBUFFERED=1
volumes:
# Maps your local paths to the container paths
- ${VIDEO_DOWNLOAD_DIR:-./downloads/video}:/downloads/video
- ${AUDIO_DOWNLOAD_DIR:-./downloads/audio}:/downloads/audio
# Mount source code for live editing
- ./app:/app/app
# Override the entrypoint to run Python directly for easier development
command: ["python", "-u", "app/main.py"]