【问题标题】:Issue when trying to play mp3 file via mciSendString (MCIERR_CANNOT_LOAD_DRIVER)尝试通过 mciSendString (MCIERR_CANNOT_LOAD_DRIVER) 播放 mp3 文件时出现问题
【发布时间】:2019-07-28 00:42:36
【问题描述】:

当尝试使用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;
        }
    }
}

【问题讨论】:

    标签: c# playback audio-player mci


    【解决方案1】:

    如果您尝试在控制台项目下运行,您可以创建一个窗口句柄并将其分配给您的类。 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...
    

    【讨论】:

      【解决方案2】:

      找到问题所在,mciSendString 无法在控制台应用程序中打开和播放 MP3 文件,但如果应用程序是 winform,它将播放它们。

      因此,如果您想通过mciSendString 播放 MP3,则需要创建一个 winform 应用程序,如果您需要控制台而不是表单,只需将表单大小设置为零并使用 AllocConsole 创建一个控制台。

      【讨论】:

        【解决方案3】:

        您的 mp3 文件在某个 USB 中?因为我不能在 USB 中播放 mp3 文件,但是当它是 HD 时我可以..

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-04
          • 1970-01-01
          • 2015-01-15
          • 1970-01-01
          • 1970-01-01
          • 2012-12-11
          相关资源
          最近更新 更多