我正在Windows 10上测试Python包:播放声音
它似乎有一些字符的路径名,如"c:\sauté“和宽字符的问题。所以它找不到文件。
命令错误275 :打开"C:\sauté.wav“别名playsound_0.4091468603477375找不到指定的文件。确保路径和文件名是正确的。
我尝试使用unicode版本的mciSendStringW()。原来,mciSendStringW根本不识别编码的命令。我不知道我现在还能做什么。
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.valueprj站点:https://pypi.org/project/playsound/ (包括安装和快速启动指南)
src代码:https://raw.githubusercontent.com/TaylorSMarks/playsound/master/playsound.py
微软mciSendString函数:https://learn.microsoft.com/en-us/previous-versions/dd757161(v=vs.85)
发布于 2019-11-02 23:46:06
当使用wide函数mciSendStringW时,不应该对字符串进行编码。因此,您的行应该简单地读command = ' '.join(command)。至少在Python3.6的Windows10机器上是这样的。
要进行双重检查,您可以运行下面的代码。第二个错误代码将是296,这只是抱怨它是错误的文件类型,因为我们创建一个空文件进行测试。
from ctypes import c_buffer, windll
from sys import getfilesystemencoding
if __name__ == '__main__':
buf = c_buffer(255)
filesystemencoding = getfilesystemencoding()
filename = r'.\sauté.wav'
# create the file if it doesn't exist
file = open(filename, 'w+')
file.close()
# ASCII
command = 'open ' + filename
byte_string_command = command.encode(filesystemencoding)
errorCode = int(windll.winmm.mciSendStringA(byte_string_command, buf, 254, 0))
# errorCode should be 275: Cannot find the file
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))
# Unicode
errorCode = int(windll.winmm.mciSendStringW(command, buf, 254, 0))
# errorCode should be 296: The specified file cannot be played
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))发布于 2019-11-05 02:27:23
没有声音,尽管它返回"0“(成功)。我的是Python3.7和Win10。我也试过utf-8,utf-16-le,没什么效果。
您需要添加
wait标志。有了这个标志,您确实可以等待被调用的函数完成。你能真正播放你的文件的原因。在你移除它的情况下,它将启动游戏,并在关闭它之后立即开始。
整个守则(ASCII):
from ctypes import c_buffer, windll
from sys import getfilesystemencoding
if __name__ == '__main__':
buf = c_buffer(255)
filesystemencoding = getfilesystemencoding()
filename = r'.\file_example.mp3'
# ASCII
command = 'open ' + filename + ' alias test2'
waitcommand = 'play test2 wait'
byte_string_command = command.encode(filesystemencoding)
waiting = waitcommand.encode(filesystemencoding)
errorCode = int(windll.winmm.mciSendStringA(byte_string_command, buf, 254, 0))
# errorCode should be 275: Cannot find the file
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))
errorCode = int(windll.winmm.mciSendStringA(waiting, buf, 254, 0))
# errorCode should be 275: Cannot find the file
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))UNICODE:
from ctypes import c_buffer, windll
from sys import getfilesystemencoding
if __name__ == '__main__':
buf = c_buffer(255)
filesystemencoding = getfilesystemencoding()
filename = r'.\file_example.mp3'
# ASCII
command = r'open ' + filename + r' alias test2'
waitcommand = r'play test2 wait'
byte_string_command = command.encode(filesystemencoding)
waiting = waitcommand.encode(filesystemencoding)
# Unicode
errorCode = int(windll.winmm.mciSendStringW(command, buf, 254, 0))
# errorCode should be 296: The specified file cannot be played
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))
errorCode = int(windll.winmm.mciSendStringW(waitcommand, buf, 254, 0))
# errorCode should be 275: Cannot find the file
errorBuffer = c_buffer(255)
windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254)
print("{}: {}".format(errorCode, errorBuffer.value.decode()))如果代码有效,它将返回0: The specified command was carried out。
注:
返回用于在Unicode文件名和字节文件名之间转换的编码名称。为了实现最好的兼容性,在所有情况下都应该使用str作为文件名,尽管也支持将文件名表示为字节。接受或返回文件名的函数应该支持str或字节,并在内部转换为系统的首选表示形式。 这种编码总是与ASCII兼容的.应该使用os.fsencode()和os.fsdecode()来确保使用正确的编码和错误模式。在UTF-8模式下,任何平台上的编码都是utf-8 .在macOS上,编码是'utf-8‘。在Unix上,编码是区域编码。在Windows上,编码可能是'utf-8‘或'mbcs',这取决于用户配置。在版本3.6中更改: Windows不再保证返回'mbcs‘。有关更多信息,请参见PEP 529和_enablelegacywindowsfsencoding()。在版本3.7中更改:在UTF-8模式下返回‘UTF-8’。
打开设备时,可以使用“别名”标志为设备指定设备标识符。此标志允许为具有冗长文件名的复合设备分配一个简短的设备标识符,并允许您打开同一文件或设备的多个实例。
如果要播放“不等待”,则需要处理
MCI_NOTIFY,设置回调窗口句柄,并在播放完成后处理MM_MCINOTIFY。 hwndCallback:如果在命令字符串中指定了“通知”标志,则为回调窗口的句柄。
发布于 2020-04-17 11:14:21
我也在测试播放声音(Python3.8,Windows 10),并且遇到了同样的问题,这个问题可以通过这个线程中的答案来解决。非常感谢所有的贡献者!
诀窍在于使用mciSendStringW而不是mciSendStringA,并在“play”命令中使用“等待”标志。
以下是修改后的代码:
def _playsoundWin(sound, block = True):
from ctypes import c_buffer, windll
from random import random
from time import sleep
def winCommand(*command):
buf = c_buffer(255)
command = ' '.join(command)
# errorCode = int(windll.winmm.mciSendStringA(command, buf, 254, 0)) # original line
errorCode = int(windll.winmm.mciSendStringW(command, buf, 254, 0))
if errorCode:
errorBuffer = c_buffer(255)
# windll.winmm.mciGetErrorStringA(errorCode, errorBuffer, 254) # original line
windll.winmm.mciGetErrorStringW(errorCode, errorBuffer, 254)
exceptionMessage = ('\n Error ' + str(errorCode) + ' for command:'
'\n ' + command +
'\n ' + errorBuffer.value)
raise PlaysoundException(exceptionMessage)
return buf.value
alias = 'playsound_' + str(random())
winCommand('open "' + sound + '" alias', alias)
# winCommand('set', alias, 'time format milliseconds') # is not needed
# durationInMS = winCommand('status', alias, 'length') # returns bytes!
# durationInMS = durationInMS.decode() # needed for the original command
# winCommand('play', alias, 'from 0 to', durationInMS)
winCommand('play', alias, 'wait') # 'wait' does the trick
if block:
pass
# sleep(float(durationInMS) / 1000.0) # don't know it's purpose https://stackoverflow.com/questions/58659364
复制相似问题