feat: handle video decode errors with transcode fallback
This commit is contained in:
1 parent
99bbc3e126
commit
3bc3c9e433
1 file changed
+27
-25
+27
-25
@@ -406,6 +406,9 @@ class VerifyWindow(QtWidgets.QMainWindow):
|
|||||||
# Wait for media loaded to get actual duration
|
# Wait for media loaded to get actual duration
|
||||||
self.media_player.durationChanged.connect(self._on_duration_changed)
|
self.media_player.durationChanged.connect(self._on_duration_changed)
|
||||||
|
|
||||||
|
# Handle video decode errors — transcode and retry
|
||||||
|
self.media_player.errorOccurred.connect(self._on_media_error)
|
||||||
|
|
||||||
def _on_duration_changed(self, dur_ms):
|
def _on_duration_changed(self, dur_ms):
|
||||||
"""QMediaPlayer reports actual video duration in ms."""
|
"""QMediaPlayer reports actual video duration in ms."""
|
||||||
vid_dur = dur_ms / 1000.0
|
vid_dur = dur_ms / 1000.0
|
||||||
@@ -424,6 +427,30 @@ class VerifyWindow(QtWidgets.QMainWindow):
|
|||||||
self.btn_play.setText("Play")
|
self.btn_play.setText("Play")
|
||||||
self.audio_player.stop()
|
self.audio_player.stop()
|
||||||
|
|
||||||
|
def _on_media_error(self, error, message):
|
||||||
|
"""Handle video decode failure — transcode to H.264 and retry."""
|
||||||
|
if getattr(self, "_transcode_attempted", False):
|
||||||
|
print(f"Video error even after transcode: {message}", file=sys.stderr)
|
||||||
|
return
|
||||||
|
print(f"Video decode error ({error.name}): {message}", file=sys.stderr)
|
||||||
|
print("Attempting fallback: transcoding to H.264 SDR...", file=sys.stderr)
|
||||||
|
self._transcode_attempted = True
|
||||||
|
|
||||||
|
if self.temp_dir is None:
|
||||||
|
self.temp_dir = tempfile.mkdtemp(prefix="verify_sync_")
|
||||||
|
preview_path = os.path.join(self.temp_dir, "preview.mp4")
|
||||||
|
transcode_dur = 30.0 if self.mode == "short" else 0
|
||||||
|
|
||||||
|
if not transcode_to_h264_sdr(self.video_path, preview_path, transcode_dur):
|
||||||
|
print("Transcode also failed — video will remain black", file=sys.stderr)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Reload with the transcoded file
|
||||||
|
self.video_path = preview_path
|
||||||
|
from PyQt6.QtCore import QUrl
|
||||||
|
self.media_player.setSource(QUrl.fromLocalFile(os.path.abspath(preview_path)))
|
||||||
|
print(f"Retrying with transcoded preview: {preview_path}")
|
||||||
|
|
||||||
def _draw_waveforms(self):
|
def _draw_waveforms(self):
|
||||||
max_pts = 200_000 if self.mode == "full" else 80_000
|
max_pts = 200_000 if self.mode == "full" else 80_000
|
||||||
|
|
||||||
@@ -670,31 +697,6 @@ def main():
|
|||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
apply_dark_theme(app)
|
apply_dark_theme(app)
|
||||||
|
|
||||||
# Check if QMediaPlayer supports the video codec; only transcode if needed
|
|
||||||
probe = QtMultimedia.QMediaPlayer()
|
|
||||||
probe.setSource(QtCore.QUrl.fromLocalFile(os.path.abspath(video_path)))
|
|
||||||
support = probe.support()
|
|
||||||
del probe
|
|
||||||
|
|
||||||
if support != QtMultimedia.QMediaPlayer.Support.Supported:
|
|
||||||
if not temp_dir:
|
|
||||||
temp_dir = tempfile.mkdtemp(prefix="verify_sync_")
|
|
||||||
preview_path = os.path.join(temp_dir, "preview.mp4")
|
|
||||||
if not os.path.exists(preview_path):
|
|
||||||
transcode_dur = 30.0 if args.mode == "short" else 0
|
|
||||||
print(f"Codec not supported by QMediaPlayer (support={support.name}), "
|
|
||||||
f"transcoding to H.264 SDR ({'%.1fs' % transcode_dur if transcode_dur else 'full'})...")
|
|
||||||
if not transcode_to_h264_sdr(video_path, preview_path, transcode_dur):
|
|
||||||
print(f"WARNING: transcode failed, using original video (may show black)", file=sys.stderr)
|
|
||||||
else:
|
|
||||||
video_path = preview_path
|
|
||||||
print(f"Preview ready: {preview_path}")
|
|
||||||
else:
|
|
||||||
video_path = preview_path
|
|
||||||
print(f"Using cached preview: {preview_path}")
|
|
||||||
else:
|
|
||||||
print(f"Codec supported by QMediaPlayer, using directly")
|
|
||||||
|
|
||||||
w = VerifyWindow(video_path, wav_a, wav_b, sr=sr, lag_sec=lag_sec,
|
w = VerifyWindow(video_path, wav_a, wav_b, sr=sr, lag_sec=lag_sec,
|
||||||
mode=args.mode, out_dir=out_dir, temp_dir=temp_dir,
|
mode=args.mode, out_dir=out_dir, temp_dir=temp_dir,
|
||||||
volume=volume)
|
volume=volume)
|
||||||
|
|||||||
Reference in new issue
Block a user