53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
"""Functions to play audio on Windows using native win32 APIs"""
|
|
|
|
import sys
|
|
|
|
from .util import pr_err
|
|
|
|
|
|
def play_mp3_win32(mp3_fname: str) -> None:
|
|
"""Play mp3 file with given path using win32 API"""
|
|
|
|
if sys.platform != "win32":
|
|
raise NotImplementedError("Function only available on Windows")
|
|
|
|
# pylint: disable-next=import-outside-toplevel
|
|
from ctypes import create_unicode_buffer, windll, wintypes # type: ignore
|
|
|
|
_get_short_path_name_w = windll.kernel32.GetShortPathNameW
|
|
_get_short_path_name_w.argtypes = [
|
|
wintypes.LPCWSTR,
|
|
wintypes.LPWSTR,
|
|
wintypes.DWORD,
|
|
]
|
|
_get_short_path_name_w.restype = wintypes.DWORD
|
|
|
|
def get_short_path_name(long_name: str) -> str:
|
|
"""
|
|
Gets the DOS-safe short path name of a given long path.
|
|
http://stackoverflow.com/a/23598461/200291
|
|
"""
|
|
output_buf_size = 0
|
|
while True:
|
|
output_buf = create_unicode_buffer(output_buf_size)
|
|
needed = _get_short_path_name_w(long_name, output_buf, output_buf_size)
|
|
if output_buf_size >= needed:
|
|
return output_buf.value
|
|
output_buf_size = needed
|
|
|
|
mci_send_string_w = windll.winmm.mciSendStringW
|
|
|
|
def mci_send(msg: str) -> None:
|
|
"""Send MCI command string"""
|
|
result = mci_send_string_w(msg, 0, 0, 0)
|
|
if result != 0:
|
|
pr_err(f"Error {result} in mciSendString {msg}. Exiting.")
|
|
sys.exit(1)
|
|
|
|
mp3_shortname = get_short_path_name(mp3_fname)
|
|
|
|
mci_send("Close All")
|
|
mci_send(f'Open "{mp3_shortname}" Type MPEGVideo Alias theMP3')
|
|
mci_send("Play theMP3 Wait")
|
|
mci_send("Close theMP3")
|