Dubbing a URL could fail with 'Unable to download video: [Errno 22] Invalid argument' on Windows: yt-dlp stamps the downloaded file's mtime with the video's upload date, and an out-of-range/invalid timestamp makes os.utime raise [Errno 22], aborting the ingest. We download to a throwaway original.* and never use its mtime, so set updatetime=False (yt-dlp --no-mtime). Regression test asserts the opt is set. No version bump. Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
mergetest
Claude Opus 4.8
parent
79f3e35682
commit
6819feb8b2
@@ -34,6 +34,13 @@ The bundled TTS model package (`pyproject.toml`) is versioned independently.
|
||||
contact — less wall-of-text, faster to act on.
|
||||
### Fixed
|
||||
|
||||
- **Dubbing a URL no longer fails with `[Errno 22] Invalid argument` on Windows.**
|
||||
yt-dlp stamps the downloaded file's modified-time with the video's upload
|
||||
date; an out-of-range/invalid timestamp makes the `os.utime` call raise
|
||||
`[Errno 22]` and aborts the whole URL ingest. OmniVoice downloads to a throwaway
|
||||
file and never uses its mtime, so it now skips the stamp entirely
|
||||
(`updatetime=False`). (#642)
|
||||
|
||||
- **Dubbing a YouTube link that 403s now retries with a different player
|
||||
client.** Some videos serve their formats signature-protected to the default
|
||||
player client, so the media download fails with `HTTP Error 403: Forbidden`
|
||||
|
||||
@@ -534,6 +534,12 @@ def yt_download_sync(
|
||||
"quiet": True,
|
||||
"no_warnings": True,
|
||||
"restrictfilenames": True,
|
||||
# Don't stamp the downloaded file's mtime with the video's upload date
|
||||
# (#642): on Windows an out-of-range/invalid timestamp makes the os.utime
|
||||
# call raise `[Errno 22] Invalid argument`, failing the whole ingest. We
|
||||
# download to a throwaway `original.*` and never use its mtime, so skip
|
||||
# it entirely (equivalent to yt-dlp's --no-mtime).
|
||||
"updatetime": False,
|
||||
"socket_timeout": 30,
|
||||
# Resilience against YouTube CDN flakes: a single empty fragment
|
||||
# (commonly the very last one — "Did not get any data blocks")
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
"""yt-dlp must not stamp the download's mtime (#642).
|
||||
|
||||
On Windows, yt-dlp stamping the temp file with the video's upload date can raise
|
||||
`[Errno 22] Invalid argument` from os.utime on an out-of-range timestamp, failing
|
||||
the whole URL ingest. We download to a throwaway file and never use its mtime, so
|
||||
`updatetime` must be False.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "backend"))
|
||||
|
||||
from services import dub_pipeline # noqa: E402
|
||||
|
||||
|
||||
def test_download_opts_disable_mtime(tmp_path, monkeypatch):
|
||||
import yt_dlp
|
||||
|
||||
captured = {}
|
||||
|
||||
class _FakeYDL:
|
||||
def __init__(self, opts):
|
||||
captured.update(opts)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *a):
|
||||
return False
|
||||
|
||||
def extract_info(self, url, download=True):
|
||||
raise RuntimeError("stop after capturing opts")
|
||||
|
||||
def prepare_filename(self, info):
|
||||
return "unused"
|
||||
|
||||
monkeypatch.setattr(yt_dlp, "YoutubeDL", _FakeYDL)
|
||||
with pytest.raises(Exception):
|
||||
dub_pipeline.yt_download_sync("https://youtu.be/abc", str(tmp_path))
|
||||
|
||||
assert captured.get("updatetime") is False, (
|
||||
"yt-dlp must set updatetime=False so a bad upload-date timestamp can't "
|
||||
"raise [Errno 22] on Windows (#642)"
|
||||
)
|
||||
Reference in New Issue
Block a user