Skip to content

Torchaudio is not detecting FFmpeg #3789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ruliworst opened this issue May 13, 2024 · 13 comments · May be fixed by #3850
Open

Torchaudio is not detecting FFmpeg #3789

ruliworst opened this issue May 13, 2024 · 13 comments · May be fixed by #3850

Comments

@ruliworst
Copy link

🐛 Describe the bug

Hi everyone,

I am trying to use torchaudio with FFmpeg but for some reason it is not being detected.

import torchaudio
print(torchaudio.list_audio_backends())

ffmpeg
ffmpeg files

I added the path 'C:\Program Files\ffmpeg\bin' to the PATH environment variable. As you can see I can execute ffmpeg from cmd. However, when I execute torchaudio.list_audio_backends() only 'soundfile' is detected. I tested this in a Python PIP (I can't use conda) virtual environment with version 3.10 and in another one with version 3.12 but, it didn't work in both. Torchaudio and torch versions are 2.2.1. I don't know if it is a problem with version compatibility but in the official documentation I saw ffmpeg 6 is supported and I checked the code which tries to load the libraries.

I checked a lot of related issues but I couldn't find the right solution.

Any suggestions are welcome!
Thanks.

Versions

Collecting environment information...

PyTorch version: 2.2.1+cpu
Is debug build: False
CUDA used to build PyTorch: Could not collect
ROCM used to build PyTorch: N/A
OS: Microsoft Windows Server 2022 Standard
GCC version: Could not collect
Clang version: Could not collect
CMake version: Could not collect
Libc version: N/A

Python version: 3.10.7 (tags/v3.10.7:6cc6b13, Sep  5 2022, 14:08:36) [MSC v.1933 64 bit (AMD64)] (64-bit runtime)
Python platform: Windows-10-10.0.20348-SP0
Is CUDA available: False
CUDA runtime version: 12.3.103
CUDA_MODULE_LOADING set to: N/A
GPU models and configuration: GPU 0: NVIDIA A100-PCIE-40GB
Nvidia driver version: 546.12
cuDNN version: Could not collect
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

CPU:
'wmic' is not recognized as an internal or external command,
operable program or batch file.

Versions of relevant libraries:

[pip3] numpy==1.26.4
[pip3] pytorch-lightning==2.2.4
[pip3] pytorch-metric-learning==2.5.0
[pip3] torch==2.2.1
[pip3] torch-audiomentations==0.11.1
[pip3] torch-pitch-shift==1.2.4
[pip3] torchaudio==2.2.1
[pip3] torchmetrics==1.4.0
[conda] Could not collect
@ruliworst
Copy link
Author

ruliworst commented May 16, 2024

Loading manullay the binaries is working but, I would like it was automatic.

ctypes.CDLL('C:/Program Files/ffmpeg/bin/avcodec-60.dll')
ctypes.CDLL('C:/Program Files/ffmpeg/bin/avdevice-60.dll')
ctypes.CDLL('C:/Program Files/ffmpeg/bin/avfilter-9.dll')
ctypes.CDLL('C:/Program Files/ffmpeg/bin/avformat-60.dll')
ctypes.CDLL('C:/Program Files/ffmpeg/bin/avutil-58.dll')

I still don't know why it is not working without preloading libraries.

@ruliworst
Copy link
Author

ruliworst commented May 16, 2024

If I locate the libraries in the same folder of libtorio_ffmpeg6.pyd , they are detected while importing. That is, in Lib/site-packages/torio/lib

EDIT: I have been checking the internal code and in file torchaudio\_extension\__init__.py line 24 there is a code which is not being executed:

if os.name == "nt" and (3, 8) <= sys.version_info < (3, 9):
    _init_dll_path()

This code adds the paths from PATH environment variable to the DLL search path. However, I would like to know why it is only executed in Python 3.8 version.

Thank you.

@chislon
Copy link

chislon commented Aug 3, 2024

Ran into this same unexpected behavior as well.

If _init_dll_path() is allowed to run it works as expected

@HarikalarKutusu
Copy link

HarikalarKutusu commented Aug 17, 2024

Same problem here, struggling for hours. Win 11, Python 3.12.4, using pip, ffmpeg 6.1.2 with shared libraries, path OK, can run on CMD, restarted multiple times, etc... Using torchaudio==2.4.0+cu124 thou...

ctypes.CDLL workaround also did not work in my case. Only "soundfile" can be used.
Adding this to the code did not help either:

os.add_dll_directory("C:\\Programs\\ffmpeg-6.1\\bin\\")

PS: I'm trying to convert my code to use torch/torchaudio. Before torchaudio I've been using PyAV without any problems - using ffmpeg for a decade. torchaudio's ffmpeg documentation is also very cryptic. As far as I can see, torchaudio moved to ffmpeg as the main cross-platform library, but still too many problems.

@chislonchow
Copy link

chislonchow commented Aug 17, 2024

Hi HarikalarKutusu, do you have all the required ffmpeg DLL files?

In my case I need all of these for ffmpeg to be detected, in addition to executing _init_dll_path from the file modified in torchaudio:

avcodec-60.dll
avdevice-60.dll
avfilter-9.dll
avformat-60.dll
avutil-58.dll
postproc-57.dll
swresample-4.dll
swscale-7.dll

Using the dlls from this ffmpeg shared build: https://github.com/GyanD/codexffmpeg/releases/tag/6.1.1

@HarikalarKutusu
Copy link

HarikalarKutusu commented Aug 17, 2024

I used [ffmpeg-builds/win64-gpl-shared-6.1](https://github.com/users/BtbN/packages/container/package/ffmpeg-builds%2Fwin64-gpl-shared-6.1), the naming of the .dll files are the same (v6.1.2 but IMO should not effect this).

I did not update the _init_dll_path directly in tourchaudio distribution, but used os.add_dll_directory() in my code before calling any torch code. This is what it does if ran:

def _init_dll_path():
    # On Windows Python-3.8+ has `os.add_dll_directory` call,
    # which is called to configure dll search path.
    # To find cuda related dlls we need to make sure the
    # conda environment/bin path is configured Please take a look:
    # https://stackoverflow.com/questions/59330863/cant-import-dll-module-in-python
    # Please note: if some path can't be added using add_dll_directory we simply ignore this path
    for path in os.environ.get("PATH", "").split(";"):
        if os.path.exists(path):
            try:
                os.add_dll_directory(path)
            except Exception:
                pass

Let me try the one from your link...
EDIT: No joy

@HarikalarKutusu
Copy link

HarikalarKutusu commented Aug 17, 2024

Joy! I was wrong.
I imported the function and called it.

from torchaudio._extension.utils import _init_dll_path
...
def my_transcode_function():
    _init_dll_path()
   ...

Also changed the v3.8 limitation code to be safe.

# if os.name == "nt" and (3, 8) <= sys.version_info < (3, 9):
#     _init_dll_path()
if os.name == "nt" and (3, 8) <= sys.version_info < (3, 99):
    _init_dll_path()

It now works. Thank you for the guidance @chislonchow !

@Achilles718611
Copy link

If I locate the libraries in the same folder of libtorio_ffmpeg6.pyd , they are detected while importing. That is, in Lib/site-packages/torio/lib

EDIT: I have been checking the internal code and in file torchaudio\_extension\__init__.py line 24 there is a code which is not being executed:

if os.name == "nt" and (3, 8) <= sys.version_info < (3, 9):
    _init_dll_path()

This code adds the paths from PATH environment variable to the DLL search path. However, I would like to know why it is only executed in Python 3.8 version.

Thank you.

Just update torchaudio/_extension/__init__.py to run _init_dll_path for all Python versions which are greater or equal than 3.8

if os.name == "nt" and (3, 8) <= sys.version_info < (3, 99):
    _init_dll_path()

@andrew-aladjev
Copy link

Docs and code that are trying to load libraries are very bad, for sure.

  1. Torchaudio is trying to load libtorio_ffmpeg*.so, for example libtorio_ffmpeg6.so. If this dynamic library won't be loaded than Torchaudio won't log anything about it.
  2. So you need to do ldd -v .venv/lib/python3.12/site-packages/torio/lib/libtorio_ffmpeg6.so and check what ffmpeg libraries are missing on your system. For example on my system libavutil.so.58, libavcodec.so.60, libavformat.so.60 and libavfilter.so.9 are missing.
  3. Than you need to find a way to install those libraries, for example a good solution is to install anaconda, activate it and use conda install -c conda-forge 'ffmpeg=6'.
  4. Now you can use LD_LIBRARY_PATH=/home/puchuu/anaconda3/lib ldd -v .venv/lib/python3.12/site-packages/torio/lib/libtorio_ffmpeg6.so and check than all ffmpeg libraries are here.
  5. Than you can disable conda and run regular python3 from command line in venv LD_LIBRARY_PATH=/home/puchuu/anaconda3/lib python3.
  6. Now you can import torchaudio and check print(torchaudio.list_audio_backends())

@andrew-aladjev
Copy link

andrew-aladjev commented Jan 16, 2025

As a result I've figured out that torchaudio package in conda-forge is broken, it has no dynamic ffmpeg libraries inside, so it is not possible to enable ffmpeg in this broken version.

BTW you can use torchaudio from pip, it works perfect (points I've mentioned above).

@Skareeg
Copy link

Skareeg commented Mar 23, 2025

After a couple hours of constant attempts at different solutions, including using the above, I managed a fully working solution by simply copying out the code from _init_dll_path in the torchaudio extensions and having it run if this is a Windows platform. Changing the version within the library code of torchaudio works just fine, yes, but I would rather not do that and want something that is replicable to anyone who would be interested in running my Jupyter notebooks without having to make such modifications.

The reason for copying the code out is because for reasons unknown to me (I am not very experienced with Python modules), simply attempting to import the _init_dll_path module and running that does not seem to want to work when I then import torchaudio down below. (As in, the FFMPEG backend is not produced, even though the PATH is added to the DLL directories.)

I am curious if just importing that method to call it is intializing the torchaudio module prematurely, as that what seems to be happening. Regardless, this is the first GitHub issue that shows in Google right now, so I wanted to contribute my findings.

FFMPEG 6 with the shared library option needs to be installed, but there is some confusion there as well. When dowloading FFMPEG manually to stick somewhere to simply add to your PATH (which is what I do, as I use FFMPEG elsewhere for other tools as well), you must use the "Windows builds by BitbN" link on the ffmpeg.org page, and then you must download the ffmpeg-n6.1.2-27-ge16ff06adb-win64-gpl-shared-6.1.zip variant, very specificallly the GPL variant, as the LGPL version is missing the postproc-57 DLL. For FFMPEG 6.1, you should have the following DLLs:

  • avcodec-60.dll
  • avdevice-60.dll
  • avfilter-9.dll
  • avformat-60.dll
  • avutil-58.dll
  • postproc-57.dll
  • swresample-4.dll
  • swscale-7.dll

It may not need all of these, but if one that it wants is missing, it tells you nothing and fails to load the FFMPEG backend. I kinda wish it would give you a bit more about what DLLs are missing (it took me 15 minutes to realize the LGPL variant of the downloads didn't have the postproc-57 DLL).

Having this all setup is the first steps, but then torchaudio is not loading the backend anyway right now because of that version check described above. Changing that code in the library works, but I would rather have something a bit more flexible for others to easily run on their machines without needing to do the same modifications.

My first thought was to run torchaudio._extension.utils._init_dll_path directly before importing torchaudio. My particular issue was that I wanted to use torchaudio.list_audio_backends immediately after importing torchaudio. For reasons that I speculated on above, that doesn't work, and it fails to load the FFMPEG backend.

What I did instead was simply copied the code out of _init_dll_path and ran it directly:

import os
import sys

# Manually call the _init_dll_path method to ensure that the system path is searched for FFMPEG.
# Calling torchaudio._extension.utils._init_dll_path does not work because it is initializing the torchadio module prematurely or something.
# See: https://github.com/pytorch/audio/issues/3789
if sys.platform == "win32":
    print("Initializing DLL path for Windows")
    for path in os.environ.get("PATH", "").split(";"):
        if os.path.exists(path):
            try:
                os.add_dll_directory(path)
            except Exception:
                pass

import torch
import torchaudio

print(torch.__version__)
print(torchaudio.__version__)
print(torchaudio.list_audio_backends())

@SvenSchoene
Copy link

SvenSchoene commented Apr 1, 2025

What I did instead was simply copied the code out of _init_dll_path and ran it directly:

import os
import sys

# Manually call the _init_dll_path method to ensure that the system path is searched for FFMPEG.
# Calling torchaudio._extension.utils._init_dll_path does not work because it is initializing the torchadio module prematurely or something.
# See: https://github.com/pytorch/audio/issues/3789
if sys.platform == "win32":
    print("Initializing DLL path for Windows")
    for path in os.environ.get("PATH", "").split(";"):
        if os.path.exists(path):
            try:
                os.add_dll_directory(path)
            except Exception:
                pass

import torch
import torchaudio

print(torch.__version__)
print(torchaudio.__version__)
print(torchaudio.list_audio_backends())

Thank you very much, I added this code at the start of my project and it works, the error disappeared!

(In fact, I put the relevant code into a file ffmpeg_windows_fix.py and import that at the beginning.)

@MagnificentCreature
Copy link

I just want to say thank you to all you legends this has been a massive headache for me for the past hour and a half.

PS for anyone who comes in the future. As of torchaudio 2.6.0, only FFMPEG version 4 to 6 work, and you must download the SHARED versoin.

You can download it here
https://github.com/GyanD/codexffmpeg/releases/download/6.1.1/ffmpeg-6.1.1-full_build-shared.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants