尝试通过 mciSendString 播放 mp3 文件时出现问题 (MCIERR_CANNOT_LOAD_DRIVER)
Issue when trying to play mp3 file via mciSendString (MCIERR_CANNOT_LOAD_DRIVER)
尝试使用 mciSendString
播放 mp3 文件时,通过以下命令:
open "{FileName}" [type mpegvideo] alias {AliasName}
//有和没有type mpegvideo
都试过了
和
play {AliasName}
我收到错误 MCIERR_CANNOT_LOAD_DRIVER : 'Unknown problem while loading the specified device driver'
。
在这篇 post 中读到您需要安装 MP3 编解码器,但我有一个,所以这不是问题。
四处搜索后,试图找出问题所在,我偶然发现了这个 project,它是一个使用 mciSendString
的音频播放器,并决定尝试一下,看看是否有同样的问题发生了,有趣的是它工作得很好并且可以播放 mp3 文件...那么问题是什么,为什么在我的项目中不起作用。
这是代码(这只是测试代码,如果没有足够的异常处理,请见谅):
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Test
{
unsafe class Program
{
[DllImport("winmm.dll", SetLastError = true)]
public static extern bool mciGetErrorString([In] int error, [In, Out] char[] buffer, [In] int bufferCount);
[DllImport("winmm.dll", SetLastError = true)]
public static extern int mciSendString([In] string command, [Optional, In, Out] char[] returnBuffer, [Optional, In] int returnBufferCount, [Optional, In] IntPtr hNotifyWindow);
static void Main(string[] args)
{
Play(@"D:\Audio\simple_beat.mp3");
Console.ReadLine();
Close();
}
static void Play(string fileName)
{
Close();
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
int error = mciSendString($"open \"{fileName}\" type mpegvideo alias RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
error = mciSendString($"open \"{fileName}\" alias RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
throw new MciException(error);
}
}
error = mciSendString($"play RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
Close();
throw new MciException(error);
}
}
}
static void Close()
{
var error = mciSendString($"close RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
throw new MciException(error);
}
}
class MciException : SystemException
{
public MciException(int error)
{
var buffer = new char[128];
if (mciGetErrorString(error, buffer, 128))
{
_message = new string(buffer);
return;
}
_message = "An unknown error has occured.";
}
public override string Message
{
get
{
return _message;
}
}
private string _message;
}
}
}
找到问题所在,mciSendString
无法在控制台应用程序中打开和播放 MP3 文件,但如果应用程序是 winform,它会播放它们。
因此,如果您想通过 mciSendString
播放 MP3,您需要创建一个 winform 应用程序,如果您需要控制台而不是表单,只需将表单大小设置为零并使用 AllocConsole
创建控制台。
你的mp3文件在某个U盘里?因为当它在USB时我不能播放mp3文件,但是当它是HD时我可以..
如果您尝试在控制台项目下 运行,您可以创建一个 window 句柄并将其分配给您的 class。 VB 示例片段:
Public Class AudioPlayer : Inherits NativeWindow : Implements IDisposable
Private piFormHandle As Integer = 0
Sub New
Me.CreateHandle(New CreateParams)
piFormHandle = Me.Handle.ToInt32
End Sub
Public Function Play()
mciSendString("play MyAlias from 0 notify", Nothing, 0, piFormHandle)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
Me.DestroyHandle()
我使用“通知”和句柄,因此我可以捕获 MM_MCINOTIFY 并检测文件结尾:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const MM_MCINOTIFY As Integer = &H3B9
Const MCI_NOTIFY_SUCCESSFUL As Integer = &H1
Select Case (m.Msg)
Case MM_MCINOTIFY
Select Case m.WParam.ToInt32()
Case MCI_NOTIFY_SUCCESSFUL
' Close device, throw events...
尝试使用 mciSendString
播放 mp3 文件时,通过以下命令:
open "{FileName}" [type mpegvideo] alias {AliasName}
//有和没有type mpegvideo
和
play {AliasName}
我收到错误 MCIERR_CANNOT_LOAD_DRIVER : 'Unknown problem while loading the specified device driver'
。
在这篇 post 中读到您需要安装 MP3 编解码器,但我有一个,所以这不是问题。
四处搜索后,试图找出问题所在,我偶然发现了这个 project,它是一个使用 mciSendString
的音频播放器,并决定尝试一下,看看是否有同样的问题发生了,有趣的是它工作得很好并且可以播放 mp3 文件...那么问题是什么,为什么在我的项目中不起作用。
这是代码(这只是测试代码,如果没有足够的异常处理,请见谅):
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Test
{
unsafe class Program
{
[DllImport("winmm.dll", SetLastError = true)]
public static extern bool mciGetErrorString([In] int error, [In, Out] char[] buffer, [In] int bufferCount);
[DllImport("winmm.dll", SetLastError = true)]
public static extern int mciSendString([In] string command, [Optional, In, Out] char[] returnBuffer, [Optional, In] int returnBufferCount, [Optional, In] IntPtr hNotifyWindow);
static void Main(string[] args)
{
Play(@"D:\Audio\simple_beat.mp3");
Console.ReadLine();
Close();
}
static void Play(string fileName)
{
Close();
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
int error = mciSendString($"open \"{fileName}\" type mpegvideo alias RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
error = mciSendString($"open \"{fileName}\" alias RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
throw new MciException(error);
}
}
error = mciSendString($"play RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
Close();
throw new MciException(error);
}
}
}
static void Close()
{
var error = mciSendString($"close RandomAudio", null, 0, IntPtr.Zero);
if (error != 0)
{
throw new MciException(error);
}
}
class MciException : SystemException
{
public MciException(int error)
{
var buffer = new char[128];
if (mciGetErrorString(error, buffer, 128))
{
_message = new string(buffer);
return;
}
_message = "An unknown error has occured.";
}
public override string Message
{
get
{
return _message;
}
}
private string _message;
}
}
}
找到问题所在,mciSendString
无法在控制台应用程序中打开和播放 MP3 文件,但如果应用程序是 winform,它会播放它们。
因此,如果您想通过 mciSendString
播放 MP3,您需要创建一个 winform 应用程序,如果您需要控制台而不是表单,只需将表单大小设置为零并使用 AllocConsole
创建控制台。
你的mp3文件在某个U盘里?因为当它在USB时我不能播放mp3文件,但是当它是HD时我可以..
如果您尝试在控制台项目下 运行,您可以创建一个 window 句柄并将其分配给您的 class。 VB 示例片段:
Public Class AudioPlayer : Inherits NativeWindow : Implements IDisposable
Private piFormHandle As Integer = 0
Sub New
Me.CreateHandle(New CreateParams)
piFormHandle = Me.Handle.ToInt32
End Sub
Public Function Play()
mciSendString("play MyAlias from 0 notify", Nothing, 0, piFormHandle)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
Me.DestroyHandle()
我使用“通知”和句柄,因此我可以捕获 MM_MCINOTIFY 并检测文件结尾:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const MM_MCINOTIFY As Integer = &H3B9
Const MCI_NOTIFY_SUCCESSFUL As Integer = &H1
Select Case (m.Msg)
Case MM_MCINOTIFY
Select Case m.WParam.ToInt32()
Case MCI_NOTIFY_SUCCESSFUL
' Close device, throw events...