MP3Player
Librería para manejar los MP3 usando MP3.dll
Reproductor *experimental*
de archivos MPEG Layer III,
usando la librería mp3.dll y empleando técnicas de
MultiThreading y Subclasificación... (vaya tela! :-)
Fecha: 23/Sep/98
(5/Sep/98)
Autor: German Oltra goltra@geocities.com
Un poco de historia:
Fecha: miércoles
26 de agosto de 1998 22:50
Asunto: Threads
Hola Guillermo...
Gracias por tu respuesta sobre el tema de los threads, entre tu y Pedro
Maicas me habeis orientado y lo he logrado!.
Entre otras cosas he podido domesticar la mp3.dll lanzandola en un thread
independiente y luego poder parar la ejecucion etc...
Si no tienes eso en tu web, quizas te gustaria como colaboracion.
Asi que recibe un cordial saludo ;-)
Fecha: jueves 27
de agosto de 1998 15:05
Asunto: RE: Threads
Pues sería interesante.
Enviame el código y un poco de explicación y lo pondré en las colaboraciones
y en la sección VB-Avanzado.
Además eso del MP3 puede que le interese a más de uno...
Gracias por adelantado.
Fecha: sábado 5
de septiembre de 1998 14:06
Asunto: RE: Threads
Bueno Guillermo, pues como lo prometido es deuda aquí te mando el
ejemplillo de la mp3.dll con multithreading y subclasificacion a saco. Ya
me contaras que te parece.
Si te parece, pones un post diciendo que tienes el ejemplo y donde
encontrarlo, que le interesa a mucha peña.
Bueno colega... saludos y hasta otra! :-)
La presentación:
Hola peña VBera
:-), para poder ejecutar el ejemplillo es necesario que copieis
el archivo mp3.dll en el directorio c:\windows\system. Y ya ta!
No he tenido tiempo de complicarme la vida en el, asi que faltan
muchas cosas... pero creo que lo principal esta ya hecho. Si le
añadis mejoras me las mandais eh???.
German Oltra
goltra@geocities.com
El código:
Un trocito de código con la declaración de las funciones y algo más:
'Copia la DLL en el directorio Windows\system\
Type PlayRecord FileName As String SeekAtStart As Long Owner As Long Result As Long End Type Declare Sub mp3gettime Lib "MP3.DLL" (DATA As PlayRecord, total As Double, perframe As Double) Declare Sub mp3play Lib "MP3.DLL" (DATA As PlayRecord) Declare Sub mp3stop Lib "MP3.DLL" () Declare Sub mp3seek Lib "MP3.DLL" (position As Integer) Dim PR as PlayRecord PR.FileName="c:\mp3\...." Call mp3play(PR)
El código del form de ejemplo y de los módulos BAS:
'El formulario (frmPlayer.frm) Option Explicit '==================================================================== ' -------------------------------- ' M P 3 - P L A Y E R ' -------------------------------- ' ' - Reproductor *experimental* de archivos MPEG Layer III, usando ' la librería mp3.dll y empleando técnicas de MultiThreading y ' Subclasificación... (vaya tela! :-) ' ' ' Germán Oltra ICQ#11765971 ' http:\\goltra.home.ml.org <goltra@geocities.com> '==================================================================== Private Total As Double Private PerFrame As Double Private ProgressTop As Integer Private ProgressValue As Integer Private Playing As Boolean 'Gestiona las acciones sobre los controles Private Sub botones_Click(Index As Integer) Select Case Index Case 0 PlayFile SetControls False, True, True, True, False Playing = True Case 1, 2: MsgBox "Las funciones de Seek no las he implementado, eso os lo dejo a vosotros! :-)" Case 3 StopFile SetControls True, False, False, False, True ProgressValue = 0 ProgressBar.AutoRedraw = True ProgressBar.Cls ProgressBar.AutoRedraw = False LCD.Caption = InTime(Total) Playing = False Case 4 Dialog.ShowOpen If Dialog.FileName = "" Then Exit Sub Mp3Info.FileName = Dialog.FileName Me.Caption = GetFileName(Dialog.FileName) SetControls True, False, False, False, True GetTime Total, PerFrame ProgressTop = Fix((Total / PerFrame) / 16) ProgressValue = 0 LCD.Caption = InTime(Total) End Select End Sub 'Secuencia de inicialización Private Sub Form_Load() HookForm Me Mp3Info.Owner = Me.hWnd Playing = False SetControls False, False, False, False, True End Sub 'Detener la interceptación de mensajes Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) unHookForm End Sub 'No puedo salir si se esta reproduciendo Private Sub Form_Unload(Cancel As Integer) If Playing Then StopFile Playing = False Cancel = 1 End If End Sub 'Activa-Desactiva los botones Private Sub SetControls(ByVal bPlay As Boolean, ByVal bRewind As Boolean, _ ByVal bForward As Boolean, ByVal bStop As Boolean, ByVal bEject As Boolean) Botones(0).Enabled = bPlay Botones(1).Enabled = bRewind Botones(2).Enabled = bForward Botones(3).Enabled = bStop Botones(4).Enabled = bEject End Sub 'Avanza la barra de progreso Private Sub PushBar() Dim Contador As Integer ProgressBar.AutoRedraw = True For Contador = 1 To Fix(ProgressBar.ScaleWidth / ProgressTop) ProgressBar.Line (ProgressValue + Contador, 0)-Step(0, ProgressBar.ScaleHeight) Next Contador ProgressBar.AutoRedraw = False ProgressValue = ProgressValue + Contador End Sub 'Destino de los mensajes interceptados Public Sub MessageReceived(ByVal Message As Long, ByVal wParam As Long, ByVal lParam As Long) Select Case Message Case FRAME_POS: LCD.Caption = InTime(Total - (PerFrame * wParam)): PushBar Case APPLY_POS: Debug.Print Now, "Seek Process Done!" Case PLAY_STOP: SetControls True, False, False, False, True: Playing = False End Select End Sub 'Muestra o esconde el *about* Private Sub LCD_Click() frmPlayer.Height = IIf(frmPlayer.Height = 3615, 1710, 3615) End Sub
'El módulo: MP3Control.bas Option Explicit '==================================================================== ' -------------------------------------------- ' MODULO DE CONTROL PARA LA LIBRERIA MP3.DLL ' -------------------------------------------- ' ' - Reproducción de los archivos MP3 en THREADS independientes ' para mantener en todo momento el control sobre el proceso. ' ' ' Germán Oltra ICQ#11765971 ' http:\\goltra.home.ml.org <goltra@geocities.com> '==================================================================== 'Tipos definidos Private Type PlayRecord FileName As String SeekAtStart As Long Owner As Long Result As Long End Type 'Constantes Globales Public Const FRAME_POS = &H2EE0 Public Const APPLY_POS = &H2EE1 Public Const PLAY_STOP = &H2EE2 'Variables Globales Public Mp3Info As PlayRecord 'Funciones Importadas de "mp3.dll" Private Declare Sub mp3gettime Lib "MP3.DLL" (DATA As PlayRecord, Total As Double, PerFrame As Double) Private Declare Sub mp3play Lib "MP3.DLL" (DATA As PlayRecord) Private Declare Sub mp3stop Lib "MP3.DLL" () Private Declare Sub mp3seek Lib "MP3.DLL" (Position As Integer) 'Funciones Importadas del API Private Declare Function CreateThread Lib "kernel32" (ByVal Null1 As Long, ByVal Null2 As Long, ByVal StartAddress As Long, Parameter As Any, ByVal Null3 As Long, ThreadId As Long) As Long 'Reproduce el archivo Private Sub StartSong() mp3play Mp3Info End Sub 'Reproduce el archivo en un thread independiente Public Sub PlayFile() Dim Identifier As Long CreateThread 0, 0, AddressOf StartSong, 0, 0, Identifier End Sub 'Obtiene la duración del archivo Public Sub GetTime(Total As Double, PerFrame As Double) mp3gettime Mp3Info, Total, PerFrame End Sub 'Situa la reproducción en un punto concreto Public Sub JumpTo(Frame As Integer) mp3seek Frame End Sub 'Para la reproducción Public Sub StopFile() mp3stop End Sub
'Módulo: PrivateEye.bas Option Explicit '==================================================================== ' ------------------------------------------ ' MODULO DE INTERCEPTACION DE MENSAJES ' ------------------------------------------ ' ' - Utilizado para "recoger" los mensajes generados por la ' libreria mp3.dll, y así poder reaccionar al respecto. ' ' ' Germán Oltra ICQ#11765971 ' http:\\goltra.home.ml.org <goltra@geocities.com> '==================================================================== 'Variables globales en el módulo Private TargetForm As Form Private TargetHandle As Long Private PrevWndProc As Long Private Const GWL_WNDPROC = (-4&) 'Funciones Importadas del API Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long 'Aquí se reciben los mensajes Private Function WndProc(ByVal hWnd As Long, ByVal uMSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long WndProc = CallWindowProc(PrevWndProc, hWnd, uMSG, wParam, lParam) If Not TargetForm Is Nothing Then TargetForm.MessageReceived uMSG, wParam, lParam End Function 'Inicia la interceptación de mensajes Public Sub HookForm(ByVal Target As Form) If Not TargetForm Is Nothing Then unHookForm Set TargetForm = Target TargetHandle = Target.hWnd PrevWndProc = SetWindowLong(TargetHandle, GWL_WNDPROC, AddressOf WndProc) End Sub 'Detiene la interceptación de mensajes Public Sub unHookForm() If TargetHandle <> 0 Then SetWindowLong TargetHandle, GWL_WNDPROC, PrevWndProc End Sub
'Módulo: AuxFuncs.bas Option Explicit '==================================================================== ' ---------------------------------------- ' FUNCIONES AUXILIARES ' ---------------------------------------- ' ' - Otras funciones utilizadas para la conversión de datos ' ' Germán Oltra ICQ#11765971 ' http:\\goltra.home.ml.org <goltra@geocities.com> '==================================================================== 'Convierte milisegundos --> String hora Public Function InTime(ByVal Milisecs As Double) As String Dim Minutes As Integer, Seconds As Integer Minutes = 0 Seconds = Fix(Milisecs / 1000) While (Seconds > 59) Seconds = Seconds - 60 Minutes = Minutes + 1 Wend InTime = Format(Minutes, "00") & ":" & Format(Seconds, "00") End Function 'Extrae el nombre de archivo de una ruta completa Public Function GetFileName(ByVal Path As String) As String Dim Contador As Integer Contador = 1 While Mid(Path, Len(Path) - Contador, 1) <> "\" Contador = Contador + 1 Wend GetFileName = Mid(Path, Len(Path) - Contador + 1) End Function
Bajate el fichero con el código de ejemplo y la librería (MP3Player.zip 84 KB)