Introduction
When I was trying to use MCI to play a media file, I searched and got some ideas from the Internet on how to use mciSendSting
. But, I had a need to know when the playback would finish. In this demo project, I have mentioned how to send a command to open, play with notify flag, and close a media, and how to receive a message when the playback is done.
It's very simple. You select a media file (MP3, Wav, ...), then click on the Play button. The Stop button will be enabled so that you can stop the playback. When the playback is completed, it will send a notification message to the form. Then, you will see the Stop button dim.
Background
For more information about MCI, please refer to MSDN. I also got some ideas from the article: Playing MP3s using MCI.
Using the code
I put all of the code work with MCI in a Media
class. So, when you want to play a media file, you just need to create a Media
object.
private Media media = new Media();
Here is the code for the Play button:
private void playButton_Click(object sender, EventArgs e)
{
if (File.Exists(mediaFileTextBox.Text))
{
media.Play(mediaFileTextBox.Text, this);
RefreshStop(true);
}
else
{
MessageBox.Show("The media file does not exist.",
"File Not Found", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
The Play
method of Media
needs two parameters: file name and form. Using this form handle, MCI will send a message to it when the playback is finished. If you want to get the message, you need to override the WinProc
method of System.Windows.Form
:
protected override void WndProc(ref Message m)
{
if (m.Msg == Media.MM_MCINOTIFY)
{
RefreshStop(false);
}
base.WndProc(ref m);
}
When the playback is complete, it will send a MM_MCINOTIFY
message. You need to check to see if it is a MM_MCINOTIFY
message. In this case, I set the Stop button on dim.
The interface of mciSendString
defined in the Media
class:
[DllImport("winmm.dll")]
private static extern long mciSendString(
string command,
StringBuilder returnValue,
int returnLength,
IntPtr winHandle);
The winHandle
is the handle of the form we need to be notified when the playback completes. Here is the code for the Play
method of the Media
class:
private void PlayMediaFile()
{
if (isOpen)
{
string playCommand = "Play " + mediaName + " notify";
mciSendString(playCommand, null, 0, notifyForm.Handle);
}
}
With the notify
and the notifyForm.Handle
, MCI will send the MM_MCINOTIFY
message to the form when the playback completes.
Here is the full source code for the Media
class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MiniPlayer
{
public class Media
{
public const int MM_MCINOTIFY = 0x3B9;
private string fileName;
private bool isOpen = false;
private Form notifyForm;
private string mediaName = "media";
[DllImport("winmm.dll")]
private static extern long mciSendString(
string command,
StringBuilder returnValue,
int returnLength,
IntPtr winHandle);
private void ClosePlayer()
{
if (isOpen)
{
String playCommand = "Close " + mediaName;
mciSendString(playCommand, null, 0, IntPtr.Zero);
isOpen = false;
}
}
private void OpenMediaFile()
{
ClosePlayer();
string playCommand = "Open \"" + fileName +
"\" type mpegvideo alias " + mediaName;
mciSendString(playCommand, null, 0, IntPtr.Zero);
isOpen = true;
}
private void PlayMediaFile()
{
if (isOpen)
{
string playCommand = "Play " + mediaName + " notify";
mciSendString(playCommand, null, 0, notifyForm.Handle);
}
}
public void Play(string fileName, Form notifyForm)
{
this.fileName = fileName;
this.notifyForm = notifyForm;
OpenMediaFile();
PlayMediaFile();
}
public void Stop()
{
ClosePlayer();
}
}
}