try again

This commit is contained in:
2026-09-13 13:12:47 +08:00
parent 5328898971
commit 53e947c506
2 changed files with 30 additions and 21 deletions

View File

@@ -90,8 +90,20 @@ _IOS_VIDEO_CODECS = {"h264", "hevc"}
_IOS_AUDIO_CODECS = {"aac", "mp3", "ac3", "eac3", "alac"} _IOS_AUDIO_CODECS = {"aac", "mp3", "ac3", "eac3", "alac"}
def _probe_stream_codecs(filepath: Path) -> Tuple[Optional[str], Optional[str]]: def _ffprobe_bin() -> Optional[str]:
ffprobe = shutil.which("ffprobe") ffprobe = shutil.which("ffprobe")
if ffprobe:
return ffprobe
ffmpeg = shutil.which("ffmpeg")
if ffmpeg:
candidate = str(Path(ffmpeg).with_name("ffprobe"))
if Path(candidate).is_file():
return candidate
return None
def _probe_stream_codecs(filepath: Path) -> Tuple[Optional[str], Optional[str]]:
ffprobe = _ffprobe_bin()
if ffprobe is None: if ffprobe is None:
return None, None return None, None
completed = subprocess.run( completed = subprocess.run(
@@ -142,13 +154,9 @@ def _ensure_ios_compatible_media(filepath: Path) -> None:
return return
ffmpeg = shutil.which("ffmpeg") ffmpeg = shutil.which("ffmpeg")
if ffmpeg is None: if ffmpeg is None:
logger.warning( raise RuntimeError(
"ffmpeg not found; skipping iOS-compatible transcode for %s (%s/%s)", f"iOS cannot play {video_codec}/{audio_codec}; ffmpeg is required to transcode {filepath.name}"
filepath.name,
video_codec,
audio_codec,
) )
return
tmp = filepath.with_suffix(".ios_tmp.mp4") tmp = filepath.with_suffix(".ios_tmp.mp4")
command = [ command = [
ffmpeg, ffmpeg,
@@ -163,7 +171,7 @@ def _ensure_ios_compatible_media(filepath: Path) -> None:
"-map", "-map",
"0:a:0?", "0:a:0?",
"-vf", "-vf",
"scale='min(1920,iw)':-2", r"scale=w=min(1920\,iw):h=-2",
"-c:v", "-c:v",
"libx264", "libx264",
"-preset", "-preset",
@@ -190,20 +198,21 @@ def _ensure_ios_compatible_media(filepath: Path) -> None:
) )
try: try:
completed = subprocess.run(command, capture_output=True, text=True, timeout=7200) completed = subprocess.run(command, capture_output=True, text=True, timeout=7200)
if completed.returncode == 0 and tmp.is_file() and tmp.stat().st_size > 0: if completed.returncode != 0 or not tmp.is_file() or tmp.stat().st_size <= 0:
tmp.replace(filepath) message = (completed.stderr or "").strip() or "unknown ffmpeg error"
logger.info("iOS-compatible transcode finished: %s", filepath.name) raise RuntimeError(
return f"Could not transcode {filepath.name} from {video_codec}/{audio_codec} to H.264/AAC: {message[-2000:]}"
logger.warning(
"iOS-compatible transcode failed for %s: rc=%d stderr=%s",
filepath.name,
completed.returncode,
(completed.stderr or "")[-400:],
) )
except (subprocess.TimeoutExpired, OSError) as exc: tmp.replace(filepath)
logger.warning("iOS-compatible transcode error for %s: %s", filepath.name, exc) except Exception:
finally:
tmp.unlink(missing_ok=True) tmp.unlink(missing_ok=True)
raise
video_codec, audio_codec = _probe_stream_codecs(filepath)
if _needs_ios_compatible_transcode(video_codec, audio_codec):
raise RuntimeError(
f"Transcoded {filepath.name} is still not iOS-compatible ({video_codec}/{audio_codec})"
)
logger.info("iOS-compatible transcode finished: %s", filepath.name)
class VideoProcessor: class VideoProcessor: