RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 991162
Accepted
DiHASTRO
DiHASTRO
Asked:2020-06-10 13:14:42 +0000 UTC2020-06-10 13:14:42 +0000 UTC 2020-06-10 13:14:42 +0000 UTC

俄语文件名和 playsound 模块

  • 772

我对python比较陌生。我需要打开一个文件,但有些文件的名称是俄语,类似于

playsound('C:/Users/User/Documents/Audacity/Секретный звук.wav') 

在这里它给了我一个错误

File "C:\Users\User\Desktop\Неизвестный.py", line 9, in <module>
playsound('C:/Users/User/Documents/Audacity/Секретный звук.wav')
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\playsound.py", line 35, in _playsoundWin
winCommand('open "' + sound + '" alias', alias)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\playsound.py", line 30, in winCommand
'\n    ' + errorBuffer.value.decode())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte

我知道您可以将此音频与代码一起放入同一个文件夹并将其重命名为英语和数字,但仍然如何在文件路径中使用俄语中的 python 中的文件本身的名称?提前致谢。

python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    insolor
    2020-06-11T01:11:10Z2020-06-11T01:11:10Z

    tl;dr :从模块作者的评论来看,截至 2021 年 7 月 15 日,该问题应该已经修复


    这是 playsound 库中的错误。让我们看一下代码:

    def winCommand(*command):
        buf = c_buffer(255)
        command = ' '.join(command).encode(getfilesystemencoding())  # <--
        errorCode = int(windll.winmm.mciSendStringA(command, buf, 254, 0))  # <--
        if errorCode:
            errorBuffer = c_buffer(255)
            windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)  # <--
            exceptionMessage = ('\n    Error ' + str(errorCode) + ' for command:'
                                '\n        ' + command.decode() +  # <--
                                '\n    ' + errorBuffer.value.decode())  # <--
            raise PlaysoundException(exceptionMessage)
        return buf.value
    

    第一个问题是它被取走getfilesystemencoding()(在Windows 10下,例如,它是utf-8),然后用这种编码对命令进行编码(其中一部分是你到带有俄罗斯字母的文件的路径)。我们得到一组 utf-8 编码的字节。然后我们将这组字节传递给函数,其名称中的mciGetErrorStringA字母A告诉我们该函数仅支持单字节编码(与W末尾有字母的函数不同——它们支持 utf-16)。该函数不起作用,返回错误代码。

    然后它起作用了if,我们尝试获取错误的文本(再次,使用函数的 ANSI 版本mciGetErrorString)。此外,最初以 utf-8 编码的命令使用默认编码进行解码(这次很幸运 - 结果也是 utf-8)。

    接下来,获取带有错误文本的缓冲区,它也是从默认编码解码的(在您的情况下,它很可能是 utf-8),但是由于 该缓冲区的内容由专为单字节编码设计的函数填充,然后缓冲区突然包含 cp1251 编码的俄语文本。我们从问题中得到一个错误。

    固定在膝盖上:

    def winCommand(*command):
        buf = c_buffer(512)
        command = ' '.join(command).encode('utf-16')
        errorCode = int(windll.winmm.mciSendStringW(command, buf, 511, 0))
        if errorCode:
            errorBuffer = c_buffer(512)
            windll.winmm.mciGetErrorStringW(errorCode, errorBuffer, 511)
            exceptionMessage = ('\n    Error ' + str(errorCode) + ' for command:'
                                '\n        ' + command.decode('utf-16') +
                                '\n    ' + errorBuffer.value.decode('utf-16'))
            raise PlaysoundException(exceptionMessage)
        return buf.value
    

    基本上,您可以向库添加拉取请求。

    更新

    我自己测试了一下,做了一些更正,函数的完整代码_playsoundWin:

    def _playsoundWin(sound, block = True):
        '''
        Utilizes windll.winmm. Tested and known to work with MP3 and WAVE on
        Windows 7 with Python 2.7. Probably works with more file formats.
        Probably works on Windows XP thru Windows 10. Probably works with all
        versions of Python.
    
        Inspired by (but not copied from) Michael Gundlach <gundlach@gmail.com>'s mp3play:
        https://github.com/michaelgundlach/mp3play
    
        I never would have tried using windll.winmm without seeing his code.
        '''
        import string
        from ctypes import c_buffer, windll
        from random import random
        from time   import sleep
        from sys    import getfilesystemencoding
    
        def winCommand(*command):
            buf = c_buffer(512)
            command = ' '.join(command)
            errorCode = int(windll.winmm.mciSendStringW(command.encode('utf-16'), buf, 511, 0))
            if errorCode:
                errorBuffer = c_buffer(512)
                windll.winmm.mciGetErrorStringW(errorCode, errorBuffer, 511)
                exceptionMessage = ('\n    Error ' + str(errorCode) + ' for command:'
                                    '\n        ' + command +
                                    '\n    ' + errorBuffer.raw.decode('utf-16').rstrip('\0'))
                
                raise PlaysoundException(exceptionMessage)
            return buf.raw.decode('utf-16').rstrip('\0')
    
        alias = ('playsound_' + str(random()))[:28]  # Avoid aliases longer then 28
        winCommand('open "' + sound + '" alias', alias)
        winCommand('set', alias, 'time format milliseconds')
        durationInMS = winCommand('status', alias, 'length')
        winCommand('play', alias, 'from 0 to', durationInMS)
    
        if block:
            sleep(float(durationInMS) / 1000.0)
    

    更新 2

    • 拉取请求:https ://github.com/TaylorSMarks/playsound/pull/32

    • 我的修复包分支:https
      ://github.com/insolor/playsound 您可以直接从 github 更新包(需要安装git):

        pip install -U git+https://github.com/insolor/playsound
      

    更新 3

    从模块作者的评论来看,他发布了他的修复版本。我没有测试过,但我认为修复是有效的,所以我删除了我的 fork。我还关闭了拉取请求,但如果您愿意,您可以查看其中的更改。

    • 3
  2. Sergey
    2020-06-10T17:30:21Z2020-06-10T17:30:21Z

    我对 windows 不是很好,但是(恕我直言)问题是 python 程序(从版本 3 开始)在 UTF-8 中工作,并且 windows 驱动器上的目录名称是用 cp1251 格式编写的。

    可能值得尝试类似的东西:

    file_name = 'C:/Users/User/Documents/Audacity/Секретный звук.wav'
    playsound(file_name.encode(encoding="cp1251")
    
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5