0

几个星期以来,我一直在兜圈子,无法解决一个令人愤怒的问题……首先;我正在运行 64 位 Win10,使用 64 位 Powershell 调用 python 3.9(也是 64 位),这是一个带有 Tk GUI 的应用程序,并使用 python-vlc。它在笔记本电脑上运行了好几个星期,我现在正试图让它在具有相同设置(Win10、64 位 VLC、64 位 Python)的 PC 上运行。

该错误可以在 Python shell 中用几行简单的行重现:

PS C:\Users\Vexen\OneDrive> python
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import vlc
>>> p = vlc.MediaPlayer("C\:\\Users\\Vexen\\OneDrive\\test.mp3")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Vexen\AppData\Local\Programs\Python\Python39\lib\site-packages\vlc.py", line 3327, in __new__
    o = instance.media_player_new()
AttributeError: 'NoneType' object has no attribute 'media_player_new'
>>>

或者,使用带有显式 .Instance() 的稍微不同的方法:

>>> import vlc
>>> i=vlc.Instance()
>>> p=i.MediaPlayer()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'MediaPlayer'

并测试我在它不起作用的机器上出来的结果:

>>> type(i)
<class 'NoneType'>

在它工作的笔记本电脑上,它显示<class 'vlc.Instance'>

以下是我看过并尝试过的东西(关于每一个的更多细节,如下):

  1. 实例化媒体播放器所需的正确代码
  2. 使用 vlc.Instance('--verbose 3')
  3. vlc.py 内置 GUI/demo 导致相同的错误
  4. 检查 VLC 是否可以打开 .mp3 文件
  5. 重新安装和 64 位检查
  6. VLC DLL 位置和 %PATH% 环境变量
  7. 检查 vlc.py
  8. vlc.py 内部问题:实例。对 _CFunctions 的new () 调用返回 None

(1)创建播放器的代码

文档说 .MediaPlayer 如果不手动完成,则会自动创建实例。此处也说明了这一点:AttributeError: 'NoneType' object has no attribute 'media_player_new'和 .

无论我采用哪种方式(直接在 Python 中,或者通过将 frmMain.vlc 设置为 vlc.MediaPlayer() 在 gui 中保持打开状态,我都会得到相同的结果,所以我在这里只展示更简单的方法。

(2) i = vlc.Instance('--verbose 3')

Python VLC 脚本错误:AttributeError: 'NoneType' object has no attribute 'media_player_new'表示使用 i = vlc.Instance('--verbose 3') 查看可能的错误消息:我的输出“C:\Windows\system32”和没有错误。

在运行良好的笔记本电脑上,它会输出一屏技术细节。

(3) vlc.py inbuilt GUI/demo 导致同样的错误

在查看 vlc.py 时,我发现它有一个内置的简单 GUI。当我运行它时,文件本身会输出相同的错误:

PS C:\Users\Vexen\OneDrive> python C:\Users\Vexen\AppData\Local\Programs\Python\Python39\Lib\site-packages\vlc.py C:\Users\Vexen\OneDrive\test.mp3
AttributeError: 'NoneType' object has no attribute 'media_new' (C:\Users\Vexen\AppData\Local\Programs\Python\Python39\Lib\site-packages\vlc.py 3.0.11115 vs LibVLC b'3.0.12 Vetinari')

这让我认为这是 VLC 安装或后端 DLL 所固有的。

(4)检查 VLC 是否可以打开 .mp3 文件

以下使 VLC 完整应用程序打开并正确播放文件:

PS C:\Users\Vexen\OneDrive> C:\Users\Vexen\OneDrive\test.mp3

此外,故意向 .MediaPlayer() 提供错误的文件路径会产生相同的错误,因此,在解析文件路径参数之前,它会遇到 NoneType 错误。

(5)重新安装和 64 位检查

许多类似的问题都集中在 32 位和 64 位安装之间的不匹配上。例如,带有 Python-VLC 的 PyInstaller:没有属性“media_player_new”错误https://superuser.com/questions/1281731/how-to-install-64-bit-vlc-library-for-64-bit-python-3-在 Windows 上。我已经卸载了 VLC 和 Python,重新启动、重新安装、重新启动并仔细检查了我已经安装了 64 位版本。

我从两台机器上卸载了它,并使用高级安装选项,使用完全相同的设置(不包括 Python 文档,包括 Tcl,包括 Python 启动器,为所有用户安装)在两台机器上进行了自定义安装。

检查两台机器上的 Python 是 64 位:

>>> import platform
>>> platform.architecture()[0]
'64bit'

获取一个新的 vlc.py 文件:

pip3 install python-vlc --force-reinstall

检查 vlc 版本,在两台机器上,细节完全匹配:

PS C:\Users\Vexen\OneDrive> python -m vlc -v
vlc.py: 3.0.11115 (Sat Jul 25 15:07:40 2020 3.0.11)
LibVLC version: 3.0.12 Vetinari (0x3000c00)
LibVLC compiler: gcc version 6.4.0 (GCC)
Plugin path: C:\WINDOWS\system32
Python: 3.9.2 (64bit) Windows 10

在运行 VLC 完整应用程序时,两台机器上的“关于”屏幕也会显示“3.0.12 Vetinari”。

32 位和 64 位不匹配有不同的错误(未找到文件、%1 不兼容等),所以,这不是问题所在。

其他一般安装问题,例如,Python vlc 安装问题在 python 中导入 VLC 模块时的属性错误,涵盖了我已经做过的一些相同的事情。

(6) VLC DLLs 位置和 %PATH% 环境变量

Python vlc 安装问题和其他一些问题与 %PATH% 和 Python 不知道在哪里寻找 vlc DLL 有关,但是,这不是我的问题。

微软表示,Sytem32 是 Windows 搜索 DLL 的默认位置:https ://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order 。

我已经浏览了 vlc.py,在“find_lib()”中,我可以看到它在 /system32/ 中找到了 libvlc.dll 的正确位置。我删除了 2x DLL 文件(另一个是 libvlccore.dll)并用新安装的 VLC 的新副本替换它们。没有区别,但是,这意味着我不需要担心 %PATH% 环境变量,因为它可以轻松自动地在 /system32/ 中找到 DLL。

此外,上面由python -m vlc -v列出的 dll 版本正确地在 /system32/ 中找到它。

(7)检查vlc.py

我已经将文件从笔记本电脑(Python 可以调用 VLC 并正常播放 .mp3 文件)复制到桌面(它会导致错误),但结果相同。文件版本看起来完全一样。

验证我确切知道正在使用哪个 vly.py;它在错误的 Stacktrace 中,并且:

>>> vlc.__file__

返回两台机器上的预期文件路径。将其复制到本地目录不会改变任何内容(除非发生在新位置的文件中,如您所料)。

我还从https://git.videolan.org/?p=vlc/bindings/python.git;a=blob;f=generated/3.0/vlc.py;h=fdb603002425e082b1d6b8ac08ab8322248d3ac7下载了最新版本的 vlc.py ;hb=头

该文件在同一行代码上产生相同的错误(尽管有几个行号不同):

  File "C:\Users\Vexen\OneDrive\Music\Pyggy\vlc.py", line 3200, in __new__
    o = instance.media_player_new()
AttributeError: 'NoneType' object has no attribute 'media_player_new'

(8) vlc.py 内部问题:Instance。对 _CFunctions 的new () 调用返回 None

它运行 find_lib() 将 dll 位置正确设置为 system32。Instance 类由 Instance 初始化(我猜)。new () ,它调用 libvlc_new() 返回 [b'vlc'],这看起来不错(它不是 None)。但它随后将其传递给 _Cfunctions(通过 f()),后者返回 None。这作为 Instance() 实例返回,是问题的根源。

我在 vlc.py 中添加了一些 print() 语句(测试时,我倾向于将“Line xxxx”放在 print 语句中,以帮助我稍后删除 prints()!):

在它不起作用的PC上:

Line 4685, lib_vlc_new() is sending the following to f(): 1 [b'vlc']
Line 4688 will return the results of f(argc, argv): None
Line 1883, Instance.__new__() is returning the following: None

在它工作的笔记本电脑上:

Line 4685, lib_vlc_new() is sending the following to f():  1 [b'vlc']
Line 4688 will return the results of f(argc, argv):  <vlc.Instance object at 0x000001DCD37BA370>
Line 1883, Instance.__new__() is returning the following:  <vlc.Instance object at 0x000001DCD37BA400>

f 是调用_Cfunctions 的子函数。

4

1 回答 1

0

在这里与开发人员社区交谈时,问题自行解决了。https://github.com/oaubert/python-vlc/issues/170

我们的结束评论包括我们最好的猜测:某处的 Windows 内部缓存。我从 system32 中删除了 DLL,以准备再次重新安装。我测试了这个程序,它从“C:\Program Files\VideoLAN\VLC\libvlc.dll”而不是/system32/目录中获取了DLL。我强烈怀疑在 Windows 的某个地方,.dll 被预加载过程或其他一些 Windows 的模糊位缓存。没有面向用户的方式来清除某些 Windows 内部缓存。缓存在某些时候变得无效(3 周似乎是一个任意的(而且相当长的)缓存期,但 Windows 是臭名昭著的不透明)。之后,它真正从新安装中加载了新版本。也许在那之前,由于预加载缓存,我所有的尝试都失败了。这只是一个猜测。

正确答案:继续尝试,即使在卸载以前的版本后,手动删除 libvlc.dll 和 libvclcore.dll ,继续重新启动,继续检查版本号。最终。它会开始工作。

于 2021-03-07T02:08:46.813 回答