From 16cd0b338e50419713b2d7bd8fea956cb593c303 Mon Sep 17 00:00:00 2001
From: jaseg <git@jaseg.de>
Date: Wed, 14 Aug 2024 11:05:01 +0200
Subject: Windows: Look for mpv.dll next to mpv.py

---
 README.rst |  5 +++--
 mpv.py     | 26 +++++++++++++++++++-------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/README.rst b/README.rst
index 1341efc..db57f22 100644
--- a/README.rst
+++ b/README.rst
@@ -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
 .............
diff --git a/mpv.py b/mpv.py
index d784db5..cd843a2 100644
--- a/mpv.py
+++ b/mpv.py
@@ -2,7 +2,7 @@
 # vim: ts=4 sw=4 et
 #
 # 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
 # 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 queue
 import os
+import os.path
 import sys
 from warnings import warn
 from functools import partial, wraps
@@ -35,19 +36,30 @@ import traceback
 
 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)
-- 
cgit