Multimídia Player utilizando APIs do Windows

Por Max Mosimann Netto, fundador e líder do grupo de usuário Codificando.net, autor de vários artigos sobre mobilidade, ministra treinamentos sobre desenvolvimento e integração de aplicações para dispositivos móveis.

Aplica-se a:

  • Microsoft .NET Framework 1.1

  • Microsoft Visual Studio 2003

  • C#

  • Windows 98, Windows ME, Windows 2000 e Windows XP

Resumo: Este artigo tem por objetivo demonstrar a utilização de C# para manipular as APIs de controle de dispositivos MCI (Media Controls Interfaces) presentes em seu computador.

Introdução

Aplicativos MCI (Media Control Devices) são dispositivos de mídia conectados ao computador como CD Players (CD-ROM), DVD Players, Videocassetes, Controladores de Áudio e etc. Irei demonstrar como chamar as APIs do Windows, para controlar estes dispositivos. Através do uso de APIs (Application Program Interface), podemos estender os recursos das linguagens de programação, possibilitando um trabalho mais profundo, como a manipulação de hardwares.

O exemplo presente neste artigo será escrito em C# e pretende utilizar a API mciSendString da DLL italic winmm.dll para criar um tocador de MP3 e MIDI.

Parte 1: Criando a interface do sistema

  1. Abra o Visual Studio .NET 2003.

  2. No menu File (Arquivo), clique em New Project (Novo Projeto).

  3. Em Project Types (Tipos de Projeto), selecione Visual C# Projects (Projetos do Visual C#).

  4. Em Templates (Modelos), selecione Windows Application.

  5. Na caixa Name (Nome), digite API_MusicPlayer e clique em OK.

Cc517974.API_MusicPlayer_img01(pt-br,MSDN.10).gif

Depois de criado, iremos adicionar os componentes que farão parte da interface:

Controle: Label

Name: lblArquivo

Text: Arquivo:

Controle: TextBox

Name: txtPathFile

Text:

Controle: Button

Name: btnOpenFile

Text: ...

Controle: OpenFileDialog

Name: openFileMP3

Text: Arquivos MP3|*.mp3|Arquivos MIDI|*.mid

Controle: Label

Name: lblTitulo

Text: Título:

Controle: Label

Name: lblArtista

Text: Artista:

Controle: Label

Name: lblAlbum

Text: Álbum::

Controle: Label

Name: lblAno

Text: Ano:

Controle: Label

Name: lblComentario

Text:

Controle: textBox

Name: txtTitulo

Text:

Controle: textBox

Name: txtArtista

Text:

Controle: textBox

Name: txtAlbum

Text:

Controle: textBox

Name: txtAno

Text:

Controle: textBox

Name: txtComentario

Text:

Cc517974.API_MusicPlayer_img02(pt-br,MSDN.10).gif

Note que existem duas imagens. Essas imagens foram criadas no Adobe Photoshop e podem ser substituídas por botões caso necessário. Para utilizá-las como buttons, "implemente" o evento click das imagens.

Parte 2: Codificando o sistema

Iremos adicionar uma nova classe a nossa solution. Para isso, acesse o menu Project -> Add Class e informe o nome clsMCI.cs

No código da classe, iremos adicionar os Namespaces necessários, como pode ser visto logo abaixo:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

O namespace System.Runtime.InteropServices é necessário para que possamos utilizar DLLs do Windows.

O namespace System.Windows.Forms é necessário para que uma classe seja capaz de exibir mensagens de alerta do tipo MessageBox.

Iremos adicionar o código necessário para fazer referencia a DLL winmm.dll que será utilizada no projeto.

[DllImport("winmm.dll", EntryPoint="mciSendString")] 
public static extern int mciSendStringA(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);

Note que fazemos a referencia a dll winmm.dll e ao método mciSendStringA da DLL. A partir da importação da DLL e do método, podemos utilizá-los como se fossem parte da estrutura da linguagem C#.

Iremos adicionar um método responsável por "inicializar" os drivers necessários para executar o arquivo de áudio. Os comentários de cada linha estão no próprio código.

private string sFileName;
public string OpenFile
{
	get
	{
		//Quanto executado como GET retorna o nome do arquivo.
		return sFileName; 
	}
	set
	{
		//Quanto executado como SET adiona o nome no arquivo na variável.
		sFileName = value; 
		
		//Caso os drivers de áudio já estejam aberto, serão fechados.
		mciSendStringA("close mMP3", null, 0, 0); 
		
		//Prepara e abre od drivers para executar o arquivo definido na variavél sFileName.
		//O arquivo a ser executado poderá ser manipulado através do alias mMP3.
		if(mciSendStringA("open " + sFileName + " type MPEGVideo alias mMP3", null, 0, 0) != 0)
		{
			//Caso o arquivo não possa ser aberto, uma mensagem de erro é exibida.
			MessageBox.Show("Erro ao abrir arquivo.");
		}  
	}
}

Iremos adicionar também, dois métodos: Um para executar o arquivo e outro para parar a executção:

public void Play()
{
	/*Enviar um sinal para o controlador MCI para que o 
	arquivo definido no alinas mMP3 seja executado.*/
	mciSendStringA("play mMP3 from 0", null, 0, 0);
}

public void Stop()
{
	/*Enviar um sinal para o controlador MCI para que a 
	execução do arquivo definido no alinas mMP3 seja parada.*/
	mciSendStringA("stop mMP3", null, 0, 0);
}

A classe está pronta e só precisamos importá-la para nosso formulário e chamar os respectivos métodos:

//Criamos uma instância da classe para usarmos seus métodos.
clsMCI myClass = new clsMCI();

private void imgPlay_Click(object sender, System.EventArgs e)
{
	/* Acionamos o método Play() da classe para que o
	arquivo aberto seja executado. */
	myClass.Play();
}

private void imgStop_Click(object sender, System.EventArgs e)
{
	/* Acionamos o método Stop() da classe para que a
	execução do arquivo aberto seja interrompida. */
	myClass.Stop();
}

private void btnOpenFile_Click(object sender, System.EventArgs e)
{
	/* A caixa de dialogo para abrir arquivos é aberta
	e arquivos do tipo MP3 e MID será listados nos diretórios. */
	openFileMP3.ShowDialog();
	
	//Caso um arquivo seja selecionado.
	if(!openFileMP3.FileName.Equals(""))
	{
		//Limpa todas as caixas de texto
		txtTitulo.Text = string.Empty;
		txtArtista.Text = string.Empty;
		txtAlbum.Text = string.Empty;
		txtAno.Text = string.Empty;
		txtComentario.Text = string.Empty;
		
		/* Se o arquivo selecionado for uma música MP3
		as caixas de texto são preenchidas com os valores das TAGs
		*/
		if(Path.GetExtension(openFileMP3.FileName.ToUpper()).Equals(".MP3"))
		{
			/* Cria uma instância da classe clsMP3TagInfo para obter
			as informações sobre a música
			*/
			clsMP3TagInfo mp3Info = new clsMP3TagInfo(openFileMP3.FileName);
			mp3Info.Read();
			txtTitulo.Text = mp3Info.Title;
			txtArtista.Text = mp3Info.Artist;
			txtAlbum.Text = mp3Info.Album;
			txtAno.Text = mp3Info.Year;
			txtComentario.Text = mp3Info.Comment;
		}

		//Atribuímos o PATH do arquivo para o método OpenFile da Classe.
		myClass.OpenFile = openFileMP3.FileName;
		
		//Exibimos apenas o nome do arquivo no textBox do formulário.
		txtPathFile.Text = Path.GetFileName(myClass.OpenFile);
	}
}

Note que adicionei os métodos myClass.Play() e myClass.Stop() no evento click de cada imagem.

Caso um arquivo .MP3 seja selecionado, o sistema é capaz de ler as ID3 Tags e puxar as informações sobre artista, album, ano e etc. Em arquivos .MID essas informações não existem.

A classe clsMP3TagInfo.cs é responsável por extrair as informações de cada arquivo .MP3. A classe possui um método (Read()) para abrir o arquivo, ler determinadas posições e extrair as informações necessárias, como pode ser visto no código abaixo:

public class clsMP3TagInfo
{
	public string sfilename;
	private string sTitle;
	private string sArtist;
	private string sAlbum;
	private string sYear;
	private string sComment;
	private int iGenreID;
	private int iTrack;

	public string Title
	{
		get { return(sTitle);}
		set { sTitle = value;}
	}
	public string Artist
	{
		get { return(sArtist);}
		set { sArtist = value;}
	}
	public string Album
	{
		get { return(sAlbum);}
		set { sAlbum = value;}
	}
	public string Year
	{
		get { return(sYear);}
		set { sYear = value;}
	}

	public string Comment
	{
		get { return(sComment);}
		set { sComment = value;}
	}

	public int GenreID
	{
		get { return(iGenreID);}
		set { iGenreID = value;}
	}

	public int Track
	{
		get { return(iTrack);}
		set { iTrack = value;}
	}

	public bool hasTag;

	public clsMP3TagInfo(string filename)
	{
		sfilename = filename;
	}

	public void Read() 
	{
		// Abre e lê 128 bytes do arquivo de áudio (MP3).
		FileStream oFileStream;
		oFileStream = new FileStream( sfilename, FileMode.Open);
		byte[] bBuffer = new byte[128];
		oFileStream.Seek(-128, SeekOrigin.End);
		oFileStream.Read(bBuffer,0, 128);
		oFileStream.Close();

		// Converte o array em string.
		Encoding  instEncoding = new ASCIIEncoding();   
		string id3Tag = instEncoding.GetString(bBuffer);

		// Se o padrão for ID3 1.x então pega os dados. 
		if (id3Tag .Substring(0,3) == "TAG") 
		{
			Title      = id3Tag.Substring(  3, 30).Trim();
			Artist     = id3Tag.Substring( 33, 30).Trim();
			Album      = id3Tag.Substring( 63, 30).Trim();
			Year     = id3Tag.Substring( 93, 4).Trim();
			Comment    = id3Tag.Substring( 97,28).Trim();

			//Obtem o número da música (track number)
			if (id3Tag[125]==0)
				Track = bBuffer[126];
			else
				Track = 0;
			this.GenreID = bBuffer[127];

			hasTag    = true;
		}
		else 
		{
			hasTag      = false;
		}
	}

}

Assim que executado, basta que um arquivo .MP3 ou .MID seja localizado e o botão Play clicado para que a música comece a rolar!

Cc517974.API_MusicPlayer_img03(pt-br,MSDN.10).gif

Espero que este artigo tenha servido para demonstrar como criar aplicações utilizando recursos externos à plataforma .NET e como podemos extender os poderes da programação. O código fonte completo do exemplo utilizado no artigo, pode ser baixado clicando aqui

Mais informações sobre usos para o método mciSendString da DLL winmm.dll podem ser obtidas clicando aqui.

Até o próximo.
Max Mosimann Netto

Page view tracker