From 823b7c666b1707933032794d063be79f00334f92 Mon Sep 17 00:00:00 2001 From: AboodXD Date: Tue, 9 Dec 2025 10:26:55 +0400 Subject: [PATCH 1/4] Fix load_torchcodec_shared_libraries on Windows Add support for locating FFmpeg DLLs on Windows. --- src/torchcodec/_core/ops.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/torchcodec/_core/ops.py b/src/torchcodec/_core/ops.py index c69a8352b..2b8f6b244 100644 --- a/src/torchcodec/_core/ops.py +++ b/src/torchcodec/_core/ops.py @@ -7,8 +7,12 @@ import io import json +import os +from pathlib import Path +import shutil +import sys import warnings -from types import ModuleType +from types import ModuleType, Tuple import torch from torch.library import get_ctx, register_fake @@ -22,7 +26,7 @@ _pybind_ops: ModuleType | None = None -def load_torchcodec_shared_libraries(): +def load_torchcodec_shared_libraries() -> Tuple[int, str]: # Successively try to load the shared libraries for each version of FFmpeg # that we support. We always start with the highest version, working our way # down to the lowest version. Once we can load ALL shared libraries for a @@ -70,7 +74,8 @@ def load_torchcodec_shared_libraries(): raise RuntimeError( f"""Could not load libtorchcodec. Likely causes: 1. FFmpeg is not properly installed in your environment. We support - versions 4, 5, 6, 7, and 8. + versions 4, 5, 6, 7, and 8. On Windows, ensure you've installed + the "full-shared" version. 2. The PyTorch version ({torch.__version__}) is not compatible with this version of TorchCodec. Refer to the version compatibility table: @@ -82,7 +87,16 @@ def load_torchcodec_shared_libraries(): ) -ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() +if sys.platform == "win32" and hasattr(os, 'add_dll_directory'): # If on Windows and Python 3.8+ + # We need to locate the directory containing FFmpeg DLLs + ffmpeg_path = shutil.which("ffmpeg") + if not ffmpeg_path: + raise RuntimeError("Could not locate FFmpeg. Ensure FFmpeg is properly installed and added to PATH.") + # Temporarily add that path + with os.add_dll_directory(str(Path(ffmpeg_path).parent.resolve())): + ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() +else: + ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() # Note: We use disallow_in_graph because PyTorch does constant propagation of From e54d08acbe73b3eb0bdd79be9a2af2a746bf6426 Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Tue, 9 Dec 2025 11:36:23 +0000 Subject: [PATCH 2/4] Minor changes + lint --- src/torchcodec/_core/ops.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/torchcodec/_core/ops.py b/src/torchcodec/_core/ops.py index 2b8f6b244..10ad48181 100644 --- a/src/torchcodec/_core/ops.py +++ b/src/torchcodec/_core/ops.py @@ -8,11 +8,11 @@ import io import json import os -from pathlib import Path import shutil import sys import warnings -from types import ModuleType, Tuple +from pathlib import Path +from types import ModuleType import torch from torch.library import get_ctx, register_fake @@ -26,7 +26,7 @@ _pybind_ops: ModuleType | None = None -def load_torchcodec_shared_libraries() -> Tuple[int, str]: +def load_torchcodec_shared_libraries() -> tuple[int, str]: # Successively try to load the shared libraries for each version of FFmpeg # that we support. We always start with the highest version, working our way # down to the lowest version. Once we can load ALL shared libraries for a @@ -75,7 +75,7 @@ def load_torchcodec_shared_libraries() -> Tuple[int, str]: f"""Could not load libtorchcodec. Likely causes: 1. FFmpeg is not properly installed in your environment. We support versions 4, 5, 6, 7, and 8. On Windows, ensure you've installed - the "full-shared" version. + the "full-shared" version which ships DLLs. 2. The PyTorch version ({torch.__version__}) is not compatible with this version of TorchCodec. Refer to the version compatibility table: @@ -87,12 +87,16 @@ def load_torchcodec_shared_libraries() -> Tuple[int, str]: ) -if sys.platform == "win32" and hasattr(os, 'add_dll_directory'): # If on Windows and Python 3.8+ +if sys.platform == "win32" and hasattr(os, "add_dll_directory"): # We need to locate the directory containing FFmpeg DLLs + # and temporarily add it to the DLL search path. + # This seems to be needed on some users machine, but not on our CI. We don't + # know why. ffmpeg_path = shutil.which("ffmpeg") if not ffmpeg_path: - raise RuntimeError("Could not locate FFmpeg. Ensure FFmpeg is properly installed and added to PATH.") - # Temporarily add that path + raise RuntimeError( + "Could not locate FFmpeg. Ensure FFmpeg is properly installed and added to PATH." + ) with os.add_dll_directory(str(Path(ffmpeg_path).parent.resolve())): ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() else: From 24db77f97cab84a8dfafcd0b24a1155adebfecec Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Tue, 9 Dec 2025 18:32:30 +0000 Subject: [PATCH 3/4] Safer stuff... maybe --- src/torchcodec/_core/ops.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/torchcodec/_core/ops.py b/src/torchcodec/_core/ops.py index 10ad48181..bea65f6ba 100644 --- a/src/torchcodec/_core/ops.py +++ b/src/torchcodec/_core/ops.py @@ -11,6 +11,7 @@ import shutil import sys import warnings +from contextlib import nullcontext from pathlib import Path from types import ModuleType @@ -93,13 +94,16 @@ def load_torchcodec_shared_libraries() -> tuple[int, str]: # This seems to be needed on some users machine, but not on our CI. We don't # know why. ffmpeg_path = shutil.which("ffmpeg") - if not ffmpeg_path: - raise RuntimeError( - "Could not locate FFmpeg. Ensure FFmpeg is properly installed and added to PATH." - ) - with os.add_dll_directory(str(Path(ffmpeg_path).parent.resolve())): - ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() + if ffmpeg_path: + + def cm(): # noqa: F811 + ffmpeg_dir = Path(ffmpeg_path).parent + return os.add_dll_directory(str(ffmpeg_dir)) # that's the actual CM + else: + cm = nullcontext + +with cm(): ffmpeg_major_version, core_library_path = load_torchcodec_shared_libraries() From 487f0be1935e0a63cd9b72aa1e53a8290686af1d Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Tue, 9 Dec 2025 18:34:20 +0000 Subject: [PATCH 4/4] nit --- src/torchcodec/_core/ops.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/torchcodec/_core/ops.py b/src/torchcodec/_core/ops.py index bea65f6ba..0d14e9cda 100644 --- a/src/torchcodec/_core/ops.py +++ b/src/torchcodec/_core/ops.py @@ -89,12 +89,10 @@ def load_torchcodec_shared_libraries() -> tuple[int, str]: if sys.platform == "win32" and hasattr(os, "add_dll_directory"): - # We need to locate the directory containing FFmpeg DLLs - # and temporarily add it to the DLL search path. - # This seems to be needed on some users machine, but not on our CI. We don't - # know why. - ffmpeg_path = shutil.which("ffmpeg") - if ffmpeg_path: + # On windows we try to locate the FFmpeg DLLs and temporarily add them to + # the DLL search path. This seems to be needed on some users machine, but + # not on our CI. We don't know why. + if ffmpeg_path := shutil.which("ffmpeg"): def cm(): # noqa: F811 ffmpeg_dir = Path(ffmpeg_path).parent