Skip to content

Commit

Permalink
Windows: Look for mpv.dll next to mpv.py
Browse files Browse the repository at this point in the history
  • Loading branch information
jaseg committed Aug 14, 2024
1 parent 3d09f51 commit 16cd0b3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
5 changes: 3 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
``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
<https://stackoverflow.com/a/23805306>`__ for details.
into ctypes, which is different to the one Windows uses internally. You can modify `%PATH%` before importing python-mpv
to modify where python-mpv looks for the DLL. Consult `this stackoverflow post <https://stackoverflow.com/a/23805306>`__
for details.

Python >= 3.9
.............
Expand Down
26 changes: 19 additions & 7 deletions mpv.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# vim: ts=4 sw=4 et
#
# Python MPV library module
# Copyright (C) 2017-2022 Sebastian Götte <[email protected]>
# Copyright (C) 2017-2024 Sebastian Götte <[email protected]>
#
# 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
Expand All @@ -24,6 +24,7 @@
import threading
import queue
import os
import os.path
import sys
from warnings import warn
from functools import partial, wraps
Expand All @@ -35,19 +36,30 @@

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.
dll = ctypes.util.find_library('mpv-2.dll') or ctypes.util.find_library('libmpv-2.dll') or ctypes.util.find_library('mpv-1.dll')
if dll is None:
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"].')
# 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
names = ['mpv-2.dll', 'libmpv-2.dll', 'mpv-1.dll']
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"].')

try:
# 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
backend = CDLL(dll, 0x00001000 | 0x00000100)
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
else:
raise OSError(f'ctypes.find_library found mpv.dll at {dll}, but ctypes.CDLL could not load it.') from e
fs_enc = 'utf-8'

else:
import locale
lc, enc = locale.getlocale(locale.LC_NUMERIC)
Expand Down

0 comments on commit 16cd0b3

Please sign in to comment.