Windows: Look for mpv.dll next to mpv.py

This commit is contained in:
jaseg 2024-08-14 11:05:01 +02:00
parent 3d09f5199e
commit 16cd0b338e
2 changed files with 22 additions and 9 deletions

View file

@ -29,8 +29,9 @@ submit a `pull request`_ on github.
On Windows you can place libmpv anywhere in your ``%PATH%`` (e.g. next to ``python.exe``) or next to this module's On Windows you can place libmpv anywhere in your ``%PATH%`` (e.g. next to ``python.exe``) or next to this module's
``mpv.py``. Before falling back to looking in the mpv module's directory, python-mpv uses the DLL search order built ``mpv.py``. Before falling back to looking in the mpv module's directory, python-mpv uses the DLL search order built
into ctypes, which is different to the one Windows uses internally. Consult `this stackoverflow post into ctypes, which is different to the one Windows uses internally. You can modify `%PATH%` before importing python-mpv
<https://stackoverflow.com/a/23805306>`__ for details. to modify where python-mpv looks for the DLL. Consult `this stackoverflow post <https://stackoverflow.com/a/23805306>`__
for details.
Python >= 3.9 Python >= 3.9
............. .............

22
mpv.py
View file

@ -2,7 +2,7 @@
# vim: ts=4 sw=4 et # vim: ts=4 sw=4 et
# #
# Python MPV library module # Python MPV library module
# Copyright (C) 2017-2022 Sebastian Götte <code@jaseg.net> # Copyright (C) 2017-2024 Sebastian Götte <code@jaseg.net>
# #
# python-mpv inherits the underlying libmpv's license, which can be either GPLv2 or later (default) or LGPLv2.1 or # python-mpv inherits the underlying libmpv's license, which can be either GPLv2 or later (default) or LGPLv2.1 or
# later. For details, see the mpv copyright page here: https://github.com/mpv-player/mpv/blob/master/Copyright # later. For details, see the mpv copyright page here: https://github.com/mpv-player/mpv/blob/master/Copyright
@ -24,6 +24,7 @@ import ctypes.util
import threading import threading
import queue import queue
import os import os
import os.path
import sys import sys
from warnings import warn from warnings import warn
from functools import partial, wraps from functools import partial, wraps
@ -35,19 +36,30 @@ import traceback
if os.name == 'nt': if os.name == 'nt':
# Note: mpv-2.dll with API version 2 corresponds to mpv v0.35.0. Most things should work with the fallback, too. # Note: mpv-2.dll with API version 2 corresponds to mpv v0.35.0. Most things should work with the fallback, too.
dll = ctypes.util.find_library('mpv-2.dll') or ctypes.util.find_library('libmpv-2.dll') or ctypes.util.find_library('mpv-1.dll') names = ['mpv-2.dll', 'libmpv-2.dll', 'mpv-1.dll']
if dll is None: for name in names:
dll = ctypes.util.find_library(name)
if dll:
break
else:
for name in names:
dll = os.path.join(os.path.dirname(__file__), name)
if os.path.isfile(dll):
break
else:
raise OSError('Cannot find mpv-1.dll, mpv-2.dll or libmpv-2.dll in your system %PATH%. One way to deal with this is to ship the dll with your script and put the directory your script is in into %PATH% before "import mpv": os.environ["PATH"] = os.path.dirname(__file__) + os.pathsep + os.environ["PATH"] If mpv-1.dll is located elsewhere, you can add that path to os.environ["PATH"].') raise OSError('Cannot find mpv-1.dll, mpv-2.dll or libmpv-2.dll in your system %PATH%. One way to deal with this is to ship the dll with your script and put the directory your script is in into %PATH% before "import mpv": os.environ["PATH"] = os.path.dirname(__file__) + os.pathsep + os.environ["PATH"] If mpv-1.dll is located elsewhere, you can add that path to os.environ["PATH"].')
try:
# flags argument: LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR # flags argument: LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
# cf. https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa # cf. https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa
try:
backend = CDLL(dll, 0x00001000 | 0x00000100) backend = CDLL(dll, 0x00001000 | 0x00000100)
except Exception as e: except Exception as e:
if not os.path.isabs(dll): if not os.path.isabs(dll): # can only be find_library, not the "look next to mpv.py" thing
raise OSError(f'ctypes.find_library found mpv.dll at {dll}, but ctypes.CDLL could not load it. It looks like find_library found mpv.dll under a relative path entry in %PATH%. Please make sure all paths in %PATH% are absolute. Instead of trying to load mpv.dll from the current working directory, put it somewhere next to your script and add that path to %PATH% using os.environ["PATH"] = os.path.dirname(__file__) + os.pathsep + os.environ["PATH"]') from e raise OSError(f'ctypes.find_library found mpv.dll at {dll}, but ctypes.CDLL could not load it. It looks like find_library found mpv.dll under a relative path entry in %PATH%. Please make sure all paths in %PATH% are absolute. Instead of trying to load mpv.dll from the current working directory, put it somewhere next to your script and add that path to %PATH% using os.environ["PATH"] = os.path.dirname(__file__) + os.pathsep + os.environ["PATH"]') from e
else: else:
raise OSError(f'ctypes.find_library found mpv.dll at {dll}, but ctypes.CDLL could not load it.') from e raise OSError(f'ctypes.find_library found mpv.dll at {dll}, but ctypes.CDLL could not load it.') from e
fs_enc = 'utf-8' fs_enc = 'utf-8'
else: else:
import locale import locale
lc, enc = locale.getlocale(locale.LC_NUMERIC) lc, enc = locale.getlocale(locale.LC_NUMERIC)