User42389041
User42389041

Reputation: 91

Issue when trying to play mp3 file via mciSendString (MCIERR_CANNOT_LOAD_DRIVER)

When trying to play a mp3 file using mciSendString, via the following commands:

open "{FileName}" [type mpegvideo] alias {AliasName} //tried both with and without type mpegvideo

and

play {AliasName}

I get the error MCIERR_CANNOT_LOAD_DRIVER : 'Unknown problem while loading the specified device driver'.

Have read in this post that you need to have a MP3 codec installed, but I do have one, so that's not the issue.

After searching around, trying to find what the issue was i stumbled upon this project, it's a audio player which uses mciSendString, and decided to try it out to see if the same issue occurs, funnily enough it worked just fine and could play mp3 files... so what is the issue, why is not working in my project.

Here is the code (This is just test code so sorry if there isn't enough exception handling):

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;
        }
    }
}

Upvotes: 0

Views: 1378

Answers (3)

DaveA
DaveA

Reputation: 43

If you are trying to run under a console project, you can create a window handle and assign it to your class. A VB example snip:

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()

I use "Notify" and the handle so I can capture MM_MCINOTIFY and detect the end of the file:

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...

Upvotes: 1

your mp3 files are in some USB? Because I can't play mp3 file when it's in a USB, but when it's in HD I can..

Upvotes: 0

User42389041
User42389041

Reputation: 91

Found what the issue was, mciSendString can not open and play MP3 files in a console application, but it will play them if the application is a winform.

So if you want to play a MP3 via mciSendString you will need to create a winform app, and if you need a console instead of a form, just set the form size to zero and use AllocConsole to create a console.

Upvotes: 1

Related Questions