Reproductor MP3 que usa el control OCX de Windows Media Player 9 oculto en la ventana y muestra información de la canción que suena, realizado en Visual Studio 2017 con VB
En este ejercicio se aprende a usar el control OCX de Windows Media Player 9 mediante la agregación de una referencia COM en el proyecto. El control no se muestra al usuario (permanece oculto en la ventana) y sus funciones se substituyen con botones y código propio. Este control ActiveX nos proporciona funcionalidades de reproducción de archivos multimedia (mp3, m3u…) sin que tengamos que crear código específico para esas funciones y con nivel de dificultad accesible a usuarios poco avanzados. Tienes disponibles 2 versiones más complejas de este ejercicio: 2 y 3.
Nota 1: los botones Prev y Next sólo funcionan si está sonando una lista de reproducción M3U, si está sonando uno de varios MP3 seleccionados desde el botón Abrir (la propiedad Multiselect de OpenFile es True) no funcionan.
Nota 2: observa que el código viene con un manejo de excepciones muy sencillo, simplemente capturar la excepción y mostrar un cuadro de mensaje informando del método en el que ha tenido lugar el error. Por ejemplo:
' Para tocar la siguiente canción' Private Sub BtPrev_Click(sender As Object, e As EventArgs) Handles BtPrev.Click Try OcxPlayer.Ctlcontrols.previous() Catch pollo As Exception MsgBox("Error en BtPrev_Stop") End Try End Sub
Agregar control ActiveX a Windows Form
El control ActiveX se añade al cuadro de herramientas con el menú Herramientas > Elegir elementos del cuadro de herramientas > Componentes COM > Windows Media Player. Aparece en las herramientas de la sección Interoperabilidad WPF. Desde ahí es muy sencillo arrastrarlo al formulario como cualquier otro control. Al hacerlo, se añaden a la solución 2 archivos: AxInterop.WMPLib.dll y Interop.WMPLib.dll. Estos 2 archivos han de estar en la misma carpeta que el ejecutable de la aplicación. En mi proyecto ya están incluidos con la opción de que se copien a la carpeta bin al compilar.
El OCX tiene el nombre de AxWindowsMediaPlayer1; puede cambiarse por otro más útil, en este ejercicio se denomina ocxPlayer. En la configuración de las propiedades del control ocxPlayer pulsando sobre él con el botón derecho elegimos el modo de visualización Invisible (equivale a «uimode = invisible» en la lista de propiedades de Visual Studio) para que el control no sea mostrado en el formulario, aunque seguimos teniendo disponiendo de todas sus funcionalidades. Conviene marcar también «Inicio automático» y elegir el volumen por defecto que tendrá el reproductor al arrancar. Las demás opciones pueden dejarse como están.
Aparte de ello, Visual Studio coloca en bin otra librería llamada stdole.dll. Es un archivo de tipo PIA (primary interop assembly) que se necesita para interoperar con objetos COM de Office, WMP, etc.
Utilidad de la aplicación
Las clases aquí utilizadas tienen muchas más características de las que se muestran, entre ellas manejo y edición de Playlists, obtención de mayor información sobre la canción, etc. Programadores con experiencia pueden hacer un programa más completo, aquí solamente se ha intentado mostrar cómo, sin necesidad de tener conocimientos avanzados en Visual Basic .NET, es factible crear aplicaciones aparentemente complejas como lo es un reproductor de archivos multimedia.
Desarrollo la aplicación
El código busca la construcción de los elementos necesarios ya que el control ActiveX está oculto:
- botones de control (abrir, reproducir, anterior, siguiente, detener, cerrar).
- etiquetas que muestran el título y el autor del archivo reproducido.
- etiquetas que muestran la duración total del archivo reproducido y el tiempo de reproducción transcurrido.
Cuadro de diálogo «Abrir archivo»:
En el cuadro de diálogo «Abrir archivo» OpenFileDialog1 se filtran los archivos mediante 2 extensiones: MP3 (archivos de audio) y M3U (listas de reproducción), pero estos filtros se pueden ajustar a nuestro gusto. Al estar oculto el control OCX de Windows Media Player no existe ventana de visualización de archivos de vídeo por lo que la extensión AVI no se incluye en los filtros del control OpenFileDialog1.
' presentar al usuario un cuadro de diálogo' ' mostrar solamente archivos M3U y MP3' Dim openFile As New OpenFileDialog With { .Filter = "Archivos Mpeg Layer 3 (*.mp3)|*.mp3|Listas de canciones (*.m3u)|*.m3u" } openFile.Multiselect = True 'es posible seleccionar varios archivos a la vez' ' si elegimos algún archivo' If openFile.ShowDialog() = DialogResult.OK Then ' abrir el archivo elegido en el reproductor' OcxPlayer.URL = openFile.FileName End If
Contador de tiempo
Se usa un control Timer para informar dinámicamente del tiempo de reproducción transcurrido para la canción que suena. El evento Tick del control Timer se configura para poder mostrar el tiempo de canción transcurrido contando los segundos pero aumentando en 1 el número de minutos cada vez que se superan los 59 segundos:
' Código para el cronómetro del tiempo del programa' Dim Minutos, Segundos As Integer ' variables para mostrar el tiempo' ' variable Segundos = diferencia en segundos entre una hora y la hora actual ' Segundos = DateDiff(DateInterval.Second, tiempo, DateTime.Now) Minutos = Segundos \ 60 Segundos = Segundos - (Minutos * 60) ' para que no supere 59' ' presentación formateada del tiempo transcurrido' lbTime.Text = Format(Minutos, "00") & ":" & Format(Segundos, "00")
Estado del reproductor
Al cambiar el estado del reproductor (playing, stopped) se desencadena el evento PlayStateChange que, al ser detectado, permite conocer el estado del reproductor. Como el OCX tiene inicio automático, simplemente con elegir un archivo ya cambia el estado de reproducción. De esta forma sabemos si el estado es reproduciendo o detenido para configurar por código opciones diferentes para cada caso.
' dependiendo del estado del reproductor' Select Case e.newState Case WMPLib.WMPPlayState.wmppsPlaying ' si reproduciendo' lbTitulo.Text = OcxPlayer.currentMedia.getItemInfobyType("title", "", 0) ' título' lbAutor.Text = OcxPlayer.currentMedia.getItemInfobyType("author", "", 0) ' autor' ' para mostrar la duración de la canción' Dim minutos As Integer Dim segundos As Integer minutos = OcxPlayer.currentMedia.duration \ 60 ' división entera entre la duración en segundos y 60' ' resto entre la duración total y el resultado de la división entera anterior' segundos = OcxPlayer.currentMedia.duration - (minutos * 60) lbTotal.Text = Format(minutos, "00") & ":" & Format(segundos, "00") Timer1.Enabled = True ' iniciar el temporizador para cronometrar la canción' Timer1.Start() Case WMPLib.WMPPlayState.wmppsStopped ' si detenido' Timer1.Stop() ' detener temporizador' Timer1.Enabled = False End Select
Control WebBrowser para mostrar el código coloreado
Existe un segundo formulario que solamente contiene un control WebBrowser. Se utiliza para mostrar el código principal del programa, coloreado con sintaxis de Visual Basic. Para conseguir el código HTML he usado la utilidad gsColorearCódigo de Guillermo Som, puedes descargarla desde el Guille.
Lo que hace esta utilidad es procesar un fragmento de código (VB, java, etc.) y convertirlo a lenguaje HTML con las etiquetas y atributos necesarios para que el código se vea coloreado según la sintaxis elegida.
Ese código HTML es el que he pegado como texto del control WebBrowser con su propiedad DocumentText.
' Para mostrar el segundo formulario con el código' Private Sub LbCode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LbCode.Click ' crear una nueva instancia de la clase formulario' Dim code As New Form2 code.ShowDialog() ' mostrar el formulario' End Sub
' control WebBrowser del segundo formulario' Me.WebBrowser1.DocumentText = "<pre style=""font-family:Arial, Helvetica, sans-serif; font-size:10pt;""> ' código HTML pegado aquí' "</pre>"
ZIP con la aplicación completa
Puedes descargarlo desde aquí.
Nota: el ajuste automático de escala del formulario que muestra la ventana de la aplicación se puede configurar de varias maneras, lo tienes en las propiedades del formulario como AutoScaleMode, la opción con la que obtengo el mejor resultado es con Dpi.