Improve robustness of final file detection after download

Enhanced the logic for finding the final downloaded file by always searching for the most recent video or audio file in the download directory and its subdirectories. This approach handles various post-processing scenarios such as merging, remuxing, and subtitle embedding, ensuring the correct file is identified even if the tracked path is invalid or missing.
This commit is contained in:
oop7
2025-11-04 22:01:34 +02:00
parent 17a33b0c9c
commit 4bbb6af693
+36 -15
View File
@@ -385,38 +385,59 @@ class DownloadThread(QThread):
if return_code == 0: if return_code == 0:
self.progress_signal.emit(100) self.progress_signal.emit(100)
self.status_signal.emit(_("download.completed"))
# Try to find the actual final file if last_file_path contains format codes or doesn't exist # Robust file finding: Always search for the most recent file
if self.last_file_path: # This handles all post-processing scenarios (merging, remuxing, subtitle embedding, etc.)
final_file_found = False
try: try:
last_path = Path(self.last_file_path) # Define video/audio extensions
# Check if the file exists as-is
if not last_path.exists():
# The file path might have format codes or incorrect characters
# Try to find the most recently modified video/audio file in the download directory
video_audio_extensions = {'.mp4', '.webm', '.mkv', '.avi', '.mov', '.flv', video_audio_extensions = {'.mp4', '.webm', '.mkv', '.avi', '.mov', '.flv',
'.m4a', '.mp3', '.opus', '.flac', '.aac', '.wav', '.ogg'} '.m4a', '.mp3', '.opus', '.flac', '.aac', '.wav', '.ogg'}
# Get all video/audio files in the download directory # First, check if last_file_path exists and is valid
if self.last_file_path:
last_path = Path(self.last_file_path)
if last_path.exists() and last_path.is_file():
# File exists at the tracked path
self.current_filename = last_path.name
final_file_found = True
logger.info(f"Found file at tracked path: {self.last_file_path}")
# If not found at tracked path, search for the most recent file
if not final_file_found:
logger.info("Searching for most recent downloaded file...")
potential_files = [] potential_files = []
# Search in download directory and subdirectories (for playlists)
for ext in video_audio_extensions: for ext in video_audio_extensions:
potential_files.extend(self.path.glob(f'*{ext}')) potential_files.extend(self.path.glob(f'*{ext}'))
# Also check subdirectories (for playlist downloads)
potential_files.extend(self.path.glob(f'*/*{ext}'))
# Sort by modification time and get the most recent one
if potential_files: if potential_files:
# Sort by modification time and get the most recent
most_recent = max(potential_files, key=lambda p: p.stat().st_mtime) most_recent = max(potential_files, key=lambda p: p.stat().st_mtime)
# Verify it was modified within the last 10 seconds (just downloaded) # Verify it was modified recently (within last 30 seconds to account for post-processing)
import time time_since_modification = time.time() - most_recent.stat().st_mtime
if time.time() - most_recent.stat().st_mtime < 10:
if time_since_modification < 30:
self.last_file_path = str(most_recent) self.last_file_path = str(most_recent)
self.current_filename = most_recent.name self.current_filename = most_recent.name
logger.info(f"Found downloaded file: {self.last_file_path}") final_file_found = True
logger.info(f"Found most recent file (modified {time_since_modification:.1f}s ago): {self.last_file_path}")
else:
logger.warning(f"Most recent file is too old ({time_since_modification:.1f}s), might not be the right one")
else:
logger.warning("No video/audio files found in download directory")
except Exception as e: except Exception as e:
logger.error(f"Error finding final file: {e}", exc_info=True) logger.error(f"Error finding final file: {e}", exc_info=True)
# Set completion status
self.status_signal.emit(_("download.completed"))
# Clean up subtitle files if they were merged, with a small delay # Clean up subtitle files if they were merged, with a small delay
# to ensure the embedding process has completed # to ensure the embedding process has completed
if self.merge_subs: if self.merge_subs: