Skip to content

Instantly share code, notes, and snippets.

@RupertAvery
Last active December 30, 2020 12:01
Show Gist options
  • Select an option

  • Save RupertAvery/dc8cd358f2d20cbb9c44929a3d5f0f44 to your computer and use it in GitHub Desktop.

Select an option

Save RupertAvery/dc8cd358f2d20cbb9c44929a3d5f0f44 to your computer and use it in GitHub Desktop.
// Implement WndProc in your own form, using the pattern below
public partial class Form1 : Form
{
private MediaPlayer mediaPlayer;
public Form1()
{
InitializeComponent();
// Subscribe to Form's OnClosing event
Closing += OnClosing;
mediaPlayer = new MediaPlayer(this);
mediaPlayer.OnNotify = OnNotify;
}
private void OnNotify(object sender, EventArgs e)
{
// Do something if media completed or was stopped.
}
private void OnClosing(object sender, CancelEventArgs e)
{
mediaPlayer.Close();
}
protected override void WndProc(ref Message m)
{
if (mediaPlayer.HandleMessage(m))
{
// in case we want to skip handling if message was already handled, we can return immediately here
}
base.WndProc(ref m);
}
}
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
/// <summary>
/// A wrapper around the Windows API mciSendString command, for playing audio files.
/// </summary>
public class MediaPlayer
{
private readonly Form _parentForm;
[DllImport("winmm.dll")]
private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);
public const int MM_MCINOTIFY = 0x3B9;
public const int MCI_NOTIFY_ABORTED = 0x4;
public const int MCI_NOTIFY_FAILURE = 0x8;
public const int MCI_NOTIFY_SUCCESSFUL = 0x1;
public const int MCI_NOTIFY_SUPERSEDED = 0x2;
/// <summary>
/// Creates a MediaPlayer associated with the specified Form
/// </summary>
/// <param name="parentForm">the <see cref="Form">Form</see> that will recieve notification messages. </param>
public MediaPlayer(Form parentForm)
{
_parentForm = parentForm;
}
/// <summary>
/// Raised when the parent form recieves a MM_MCINOTIFY message.
/// The Paremt form must override <see cref="Form.WndProc"/> and call this instance's <see cref="HandleMessage"/>
/// </summary>
public EventHandler OnNotify { get; set; }
/// <summary>
/// Opens a device of type <c>MPEGVideo</c> using the specified file and associates it with the specified alias
/// </summary>
/// <param name="file"></param>
/// <param name="alias"></param>
public void Open(string file, string alias = "MediaFile")
{
mciSendString($@"open ""{file}"" type MPEGVideo alias {alias}", null, 0, IntPtr.Zero);
}
/// <summary>
/// Plays the previously opened device associated with the specified alias
/// </summary>
/// <param name="notify">If <c>true</c>, <see cref="OnNotify"/> will be raised when the media completes playback, or is stopped.</param>
/// <param name="alias"></param>
public void Play(bool notify = true, string alias = "MediaFile")
{
string command = $"play {alias} {(notify ? "notify":"")}";
mciSendString(command, null, 0, _parentForm.Handle);
}
/// <summary>
/// Pauses the device associated with the specified alias
/// </summary>
/// <param name="alias"></param>
public void Pause(string alias = "MediaFile")
{
string command = $"pause {alias}";
mciSendString(command, null, 0, IntPtr.Zero);
}
/// <summary>
/// Resumes the device associated with the specified alias
/// </summary>
/// <param name="alias"></param>
public void Resume(string alias = "MediaFile")
{
string command = $"resume {alias}";
mciSendString(command, null, 0, IntPtr.Zero);
}
/// <summary>
/// Stops the device associated with the specified alias. This will raise a notification. Use <see cref="Close"/> if you want to open a new media
/// </summary>
/// <param name="alias"></param>
public void Stop(string alias = "MediaFile")
{
string command = $"stop {alias}";
mciSendString(command, null, 0, IntPtr.Zero);
}
/// <summary>
/// Closes the device associated with the specified alias
/// </summary>
/// <param name="alias"></param>
public void Close(string alias = "MediaFile")
{
string command = $"close {alias}";
mciSendString(command, null, 0, IntPtr.Zero);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns><c>true</c> if the message was <see cref="MM_MCINOTIFY"/></returns>
public bool HandleMessage(Message m)
{
if (m.Msg == MM_MCINOTIFY)
{
OnNotify?.Invoke(this, EventArgs.Empty);
return true;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment