Winmm.dll不返回文件长度

问题描述 投票:0回答:1

我正在尝试使用winmm.dll(ctypes.windll.winmm)在python中播放.mp3文件。但是,当我尝试以毫秒为单位获取某个文件的长度,而不是实际长度(05:23 =约323000 ms)时,我得到的只是3。status命令获得的时间格式为“ m”,并且此后不会更改设置命令。这是一些说明问题的代码:

from ctypes import windll, c_buffer

fp = 'song.mp3'
alias = 'test'

buf = c_buffer(255)
r = windll.winmm.mciSendStringW(f'open "{fp}" alias {alias}', buf, 254, 0)
print(r)

buf = c_buffer(255)
r = windll.winmm.mciSendStringW(f'status {alias} time format', buf, 254, 0)
print(r, buf.value)

buf = c_buffer(255)
r = windll.winmm.mciSendStringW(f'set {alias} time format milliseconds', buf, 254, 0)
print(r)

buf = c_buffer(255)
r = windll.winmm.mciSendStringW(f'status {alias} time format', buf, 254, 0)
print(r, buf.value)

buf = c_buffer(255)
r = windll.winmm.mciSendStringW(f'status {alias} length', buf, 254, 0)
print(r, buf.value)

及其输出:

0
0 b'm'
0
0 b'm'
0 b'3'

感谢您的帮助!

python c dll ctypes winmm
1个回答
0
投票

正如我在评论中指定的,这是一个经典的[[Undefined Behavior示例。检查[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)了解更多详细信息。

列出[Python 3.Docs]: ctypes - A foreign function library for Python

code00.py

#!/usr/bin/env python3 import sys import ctypes as ct from ctypes import wintypes as wt def main(*argv): winmm_dll = ct.WinDLL("Winmm.dll") mciSendString = winmm_dll.mciSendStringW mciSendString.argtypes = (wt.LPCWSTR, wt.LPWSTR, wt.UINT, wt.HANDLE) mciSendString.restype = wt.DWORD file_name = "./SampleAudio_0.4mb.mp3" # Downloaded from https://www.sample-videos.com/audio/mp3/crowd-cheering.mp3 alias_name = "test00" status_commands = [ f"status {alias_name} time format", f"status {alias_name} length", ] commands = [f"open \"{file_name}\" alias {alias_name}"] commands.extend(status_commands) commands.append(f"set {alias_name} time format ms") commands.extend(status_commands) commands.append(f"close {alias_name}") out_buf_len = 0xFF out_buf = ct.create_unicode_buffer(out_buf_len) for command in commands: print(f"Sending {command}...") res = mciSendString(command, out_buf, out_buf_len, None) print(f" Result: {res}\n Output: {out_buf.value}") if __name__ == "__main__": print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) main(*sys.argv[1:]) print("\nDone.")

输出:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q059343461]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Sending open "./SampleAudio_0.4mb.mp3" alias test00... Result: 0 Output: 1 Sending status test00 time format... Result: 0 Output: milliseconds Sending status test00 length... Result: 0 Output: 27746 Sending set test00 time format ms... Result: 0 Output: Sending status test00 time format... Result: 0 Output: milliseconds Sending status test00 length... Result: 0 Output: 27746 Sending close test00... Result: 0 Output: Done.
© www.soinside.com 2019 - 2024. All rights reserved.