Public Class WindowMediaElement
Public Sub New()
' Esta llamada es exigida por el diseñador.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
'----------------------------------------------------------
' valor para el timer
'----------------------------------------------------------
Call InicializarLosTimer()
'----------------------------------------------------------
' Carga del video de fondo y Arrancar el video
'----------------------------------------------------------
Call CargarElVideo()
'----------------------------------------------------------
' La ventana
'----------------------------------------------------------
Me.WindowState = WindowState.Maximized
'Me.Topmost = True
Me.ShowInTaskbar = True
End Sub
#Region "Obtener Nombre Ensamblado"
' Obtener el nombre del ensamblado' esto obtiene la DLL o el EXE según
Private CampoNombreCompletoDelEnsambladoString As String = String.Empty
' Solo necesito la ruta
Private CampoRutaDelEnsambladoString As String = String.Empty
'
'''
''' Esta función obtiene la ruta del ensamblado donde se esta ejecutando esta clase
'''
'''
''' Una cadena que contiene (unicamente) la ruta donde se esta ejecutando el ensamblado
'''
'''
''' Esta programado mediante la instancia 'perezosa'
''' de forma que primero se comprueba si existe, y si no existe se calcula
''' de manera que la siguiente vez que se pida este valor se devolverá rápidamente
'''
Private Function ObtenerRutaDelEnsamblado() As System.String
If String.IsNullOrWhiteSpace(CampoRutaDelEnsambladoString) Then
'------------------------------------------------------
'Calculo de los valores de los campos de la clase
'------------------------------------------------------
'Paso A) Obtener el nombre del ensamblado' esto obtiene la DLL o el EXE según
' si el campo es Null calcularlo
If String.IsNullOrWhiteSpace(CampoNombreCompletoDelEnsambladoString) Then
CampoNombreCompletoDelEnsambladoString = System.Reflection.Assembly.GetExecutingAssembly().Location
'------------------------------------------
' Control paranoico
If String.IsNullOrWhiteSpace(CampoNombreCompletoDelEnsambladoString) Then
Throw New System.IO.FileNotFoundException("No he podido cargar el nombre del ensamblado")
End If
End If
'-------------------------------------
'Paso B) solo necesito la ruta
' si el campo es Null calcularlo
If String.IsNullOrWhiteSpace(CampoRutaDelEnsambladoString) Then
' solo necesito la ruta del ensamblado
CampoRutaDelEnsambladoString = System.IO.Path.GetDirectoryName(CampoNombreCompletoDelEnsambladoString)
'------------------------------------------
' Control paranoico
If String.IsNullOrWhiteSpace(CampoRutaDelEnsambladoString) Then
Throw New System.IO.FileNotFoundException("No he podido calcular (extraer) la ruta del ensamblado")
End If
End If
End If
'-------------------------------------
'Paso C) Devolver SOLO la ruta del ensamblado
Return CampoRutaDelEnsambladoString
End Function
#End Region
#Region "CargarElVideo"
'''
''' la función Carga la propiedad [myMediaElement.Source]
''' con el nombre completo del video que se va a mostrar
'''
'''
'''
''' El nombre del video esta declarado en la función.
'''
'''
''' Como dato de salida, la función Carga la propiedad [myMediaElement.Source]
''' del objeto MediaElement definido en XAML
'''
'''
''' IMPORTANTE
''' En este ejemplo, El video TIENE que estar en una carpeta
''' [03_Vistas_Layer\0370_Iconos]
''' Que cuelga del directorio donde esta la aplicación
'''
'''
'''
''' Se produce cuando no se encuentra el fichero en el disco
''' En condiciones normales se produce porque en la opciones avanzadas (del video)
''' hay que establecer como acción de compilación:ninguna y en
''' Copiar en el directorio de salida:copiar si es posterior
'''
''' Cualquier error no previsto
Private Sub CargarElVideo()
Dim UriDeSalida As Uri = Nothing
Dim NombreCompletoVideoString As String = String.Empty
Try
'-------------------------------------------------------------------
' Solo necesito la ruta. si el campo es Null calcularlo
If String.IsNullOrWhiteSpace(CampoRutaDelEnsambladoString) Then
' solo necesito la ruta del ensamblado
CampoRutaDelEnsambladoString = ObtenerRutaDelEnsamblado()
End If
' Montar el nombre completo añadiendo las carpetas a la ruta del ensamblado
' Estas carpetas son las carpetas donde esta colocado el video en el proyecto
' y al compilarlas se copian en el directorio de salida
'
NombreCompletoVideoString = System.IO.Path.Combine(CampoRutaDelEnsambladoString, "03_Vistas_Layer")
NombreCompletoVideoString = System.IO.Path.Combine(NombreCompletoVideoString, "0370_Iconos")
NombreCompletoVideoString = System.IO.Path.Combine(NombreCompletoVideoString, "2023-11-08_010_Ordesa.mp4")
'--------------------------------------
'Control paranoico. Comprobar que el fichero existe
If System.IO.File.Exists(NombreCompletoVideoString) = False Then
Dim mensajeError As String
Using sw As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture)
sw.WriteLine()
sw.WriteLine("ERROR - En el proceso de comprobación de la existencia del video")
sw.WriteLine("ERROR - No se encuentra el fichero en el disco")
sw.WriteLine("PROBLEMAS - No se puede cargar el video")
sw.WriteLine("INFORMACIÓN - Se interrumpe la ejecución de esta función")
sw.Flush()
mensajeError = sw.ToString
End Using
Throw New System.IO.FileNotFoundException(mensajeError, NombreCompletoVideoString)
End If
'--------------------------------------
' Crear el objeto URI para la propiedad [myMediaElement.Source]
UriDeSalida = New Uri(NombreCompletoVideoString)
'----------------------------------------------------------
' Carga del video
myMediaElement.BeginInit()
myMediaElement.Source = UriDeSalida
myMediaElement.EndInit()
'--------------------------------------
'Control paranoico. Para arrancar el video
If myMediaElement.Source IsNot Nothing Then
If Not String.IsNullOrWhiteSpace(myMediaElement.Source.AbsoluteUri) Then
myMediaElement.Play()
End If
End If
'---------------------------------------------------------
'---------------------------------------------------------
Catch ex As system.Exception
Dim mensajeError As String
Using sw As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture)
sw.WriteLine()
sw.WriteLine("----")
sw.WriteLine("ERROR ")
sw.WriteLine("SITUACIÓN {0} > {1} > {2}",
System.Reflection.MethodBase.GetCurrentMethod.Module.Name,
System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name,
System.Reflection.MethodBase.GetCurrentMethod.Name)
sw.WriteLine("{0,-16} [{1}]",
"Fecha local ",
DateTime.Now.ToString("F", System.Globalization.CultureInfo.CurrentCulture))
sw.WriteLine("----")
sw.WriteLine("----")
sw.WriteLine("Esta función [{0}] genera un nombre completo (ruta + nombre + extension)",
System.Reflection.MethodBase.GetCurrentMethod.Name)
sw.WriteLine("de fichero que se corresponde con un fichero del disco")
sw.WriteLine("[Regla de negocio] El fichero DEBE ser el de una video")
sw.WriteLine("[Regla de negocio] El fichero DEBE existir en el disco")
sw.WriteLine("Una vez que se ha encontrado, se instancia una URI ")
sw.WriteLine("se carga en un objeto [MediaElement]")
sw.WriteLine("y se muestra en el formulario")
sw.WriteLine("así: [myMediaElement.Source = UriDeSalida]")
sw.WriteLine("----")
sw.WriteLine("PROBLEMAS")
sw.WriteLine("----")
sw.WriteLine("Valores de trabajo de la clase")
If String.IsNullOrWhiteSpace(CampoNombreCompletoDelEnsambladoString) = True Then
sw.WriteLine("La cadena con el nombre completo del ensamblado tiene un valor [NULL] ¡¡ PROBLEMA !!")
Else
sw.WriteLine("Cadena con el nombre del ensamblado: [{0}]", CampoNombreCompletoDelEnsambladoString)
End If
If String.IsNullOrWhiteSpace(CampoRutaDelEnsambladoString) = True Then
sw.WriteLine("La cadena con la ruta del ensamblado tiene un valor [NULL] ¡¡ PROBLEMA !!")
Else
sw.WriteLine("Cadena con la ruta del ensamblado: [{0}]", CampoRutaDelEnsambladoString)
End If
If String.IsNullOrWhiteSpace(NombreCompletoVideoString) = True Then
sw.WriteLine("La cadena con el nombre completo del fichero de video tiene un valor [NULL] ¡¡ PROBLEMA !!")
Else
sw.WriteLine("Cadena con el nombre del fichero de video: [{0}]", NombreCompletoVideoString)
If System.IO.File.Exists(NombreCompletoVideoString) = False Then
sw.WriteLine("Fichero de video ¿Esta grabado en disco? : [NO EXISTE] ¡¡ PROBLEMA !! ")
Else
sw.WriteLine("Fichero de video ¿Esta grabado en disco? : [ENCONTRADO]")
End If
End If
If UriDeSalida Is Nothing Then
sw.WriteLine("El Objeto URI con el nombre completo del fichero tiene un valor [NULL] ¡¡ PROBLEMA !!")
Else
sw.WriteLine("El Objeto URI tiene el valor: [{0}]", UriDeSalida.AbsoluteUri)
End If
If myMediaElement.Source IsNot Nothing Then
sw.WriteLine("El Objeto MediaElement que reproducirá el video tiene un valor [NULL] ¡¡ PROBLEMA !!")
Else
sw.WriteLine("El Objeto MediaElement tiene el valor: [{0}]", myMediaElement.Source.AbsoluteUri)
End If
sw.WriteLine("----")
sw.WriteLine("Datos del error")
sw.WriteLine("----")
sw.WriteLine("Mensaje de error del sistema:")
If ex Is Nothing Then
sw.WriteLine("Problema, el valor de la excepción recibida es Null")
Else
If ex.GetType Is Nothing Then
sw.WriteLine("Problema, el valor de la excepción [ex.GetType] recibida es Null")
Else
sw.WriteLine("GetType: [{0}]", ex.GetType.ToString)
End If
'
sw.WriteLine("Message: [{0}]", ex.Message)
End If
sw.WriteLine("/ Eof")
sw.Flush()
mensajeError = sw.ToString
End Using
'--------------------------------------------------------
' Disparar el error
Throw New ArgumentException(mensajeError, NombreCompletoVideoString)
' /FIN del error
End Try
End Sub
#End Region
#Region "Botón Close"
Private Sub BotonCloseCommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs)
Call AccionCerrarFormulario()
e.Handled = True
End Sub
'''
''' Proceso de cerrar los objetos que manejan el Video
''' y el Timer antes de cerrar el formulario
'''
Private Sub AccionCerrarFormulario()
' Destruir los objeto timer usados
Call DisposeTimer()
' Cerrar el media elemento
myMediaElement.Close()
' Cerrar el form
Me.Close()
End Sub
#End Region
#Region "myMediaElement"
' Se dispara cuando se acaba de cargar (el 'video')
Sub OnMouseDownPlayMedia(ByVal sender As Object, ByVal args As MouseButtonEventArgs)
' El método Play iniciará el medio (el 'video') si no está actualmente activo o
' reanudar el medio (el 'video') si está en pausa.
' Esto no tiene ningún efecto si los medios (el 'video') están ya corriendo.
myMediaElement.Play()
' Iniciar las propiedades del elemento MediaElement.
InitializeMediaElementPropertyValues()
End Sub
'El método Play se puede utilizar para reanudar la ejecución (del 'video')
Private Sub MediaPlay()
' El método Play iniciará el medio (el 'video') si no está actualmente activo o
' reanudar el medio (el 'video') si está en pausa.
' Esto no tiene ningún efecto si el medio (el 'video') esa corriendo.
myMediaElement.Play()
End Sub
' Pausar los medios (el 'video')
Private Sub MediaPause()
' El método Pausa, pausa el medio (el 'video') si se está ejecutando actualmente.
' El método Play se puede utilizar para reanudar (el 'video').
myMediaElement.Pause()
End Sub
' Detener los medios. (el 'video')
Private Sub MediaStop()
' El método Stop detiene y restablece los medios (el 'video')
' que se reproducirán desde el principio.
myMediaElement.Stop()
End Sub
' Cambia el volumen de los medios. (el 'video')
Private Sub CambiaElVolumen(ByVal sender As Object, ByVal args As RoutedPropertyChangedEventArgs(Of Double))
myMediaElement.Volume = System.Convert.ToDouble(ControlDeslizanteVolumen.Value)
End Sub
'Cambiar la velocidad de los medios. (el 'video')
Private Sub CambiaLaVelocidadDeReproduccion(ByVal sender As Object, ByVal args As RoutedPropertyChangedEventArgs(Of Double))
myMediaElement.SpeedRatio = System.Convert.ToDouble(ControlDeslizanteVelocidad.Value)
End Sub
' Cuando se abre el medio, (el 'video') inicializa el valor máximo del control deslizante "Buscar"
' al número total de milisegundos de duración del clip multimedia.
Private Sub MediaElement_MediaOpened(ByVal sender As Object, ByVal args As RoutedEventArgs)
timelineSlider.Maximum = myMediaElement.NaturalDuration.TimeSpan.TotalMilliseconds
End Sub
' Este evento se dispara cuando acaba el video
' Cuando finaliza la reproducción multimedia.
' Detener los medios para buscar el inicio de los medios.
Private Sub MediaElement_MediaEnded(ByVal sender As Object, ByVal args As RoutedEventArgs)
' Cuando acaba la reproducción, vuelvo a repetir el video
' Para que funcione hay que pararlo y arrancarlo
' Primero lo paro
Call MediaStop()
' Después lo pongo en marcha
Call MediaPlay()
End Sub
' Saltar a diferentes partes del medio (buscar).
Private Sub ControlDeslizanteBuscarPosicion(sender As Object, e As RoutedPropertyChangedEventArgs(Of Double))
Dim ControlDeslizanteBuscarPosicion As Integer = CType(timelineSlider.Value, Integer)
' El constructor sobrecargado toma los argumentos días, horas, minutos, segundos, milisegundos.
' Crea un TimeSpan con milisegundos iguales al valor del control deslizante.
Dim ts As New TimeSpan(0, 0, 0, 0, ControlDeslizanteBuscarPosicion)
myMediaElement.Position = ts
End Sub
' Establece el volumen inicial y la relación de velocidad del medio al
' valor actual de sus respectivos controles deslizantes.
Private Sub InitializeMediaElementPropertyValues()
myMediaElement.Volume = System.Convert.ToDouble(ControlDeslizanteVolumen.Value)
myMediaElement.SpeedRatio = System.Convert.ToDouble(ControlDeslizanteVelocidad.Value)
End Sub
#End Region
#Region "Timer [System.Windows.Threading.DispatcherTimer]"
' Se dispara cada segundo para simular el movimiento del secudero de un reloj
Private TimerUnSegundo As New System.Windows.Threading.DispatcherTimer
Private Sub InicializarLosTimer()
'
' Definir los eventos como en C#"
'
'' A) El objeto que dispara el evento
' * Private TimerUnSegundo As New System.Windows.Threading.DispatcherTimer
'
'' B) Definir el evento
'' * [TimerUnSegundo.Tick] es el nombre del evento
'' * [AddressOf TimerUnSegundo_Tick] apunta a la función que tiene el código del escuchador del evento
AddHandler TimerUnSegundo.Tick, AddressOf TimerUnSegundo_Tick
'
'' C) La función escuchador del evento (Escrita a continuación)
' * Private Sub TimerUnSegundo_Tick(sender As Object, e As EventArgs)
'
TimerUnSegundo.Stop()
TimerUnSegundo.Interval = TimeSpan.FromSeconds(1) ' 1 segundo
TimerUnSegundo.Start()
End Sub
'''
''' Escuchador del evento [Tick] del objeto [TimerUnSegundo]
''' Se dispara cada segundo para simular el movimiento del secudero de un reloj
'''
Private Sub TimerUnSegundo_Tick(sender As Object, e As EventArgs)
'' ------
'' parar el timer y hacer las operaciones
'Me.TimerUnSegundo.Stop()
'' ------
If myMediaElement.Source IsNot Nothing Then
If myMediaElement.NaturalDuration.HasTimeSpan Then
Me.TextBlockTiempos.Text = String.Format("{0} / {1}",
myMediaElement.Position.ToString("mm\:ss"),
myMediaElement.NaturalDuration.TimeSpan.ToString("mm\:ss"))
End If
Else
Me.TextBlockTiempos.Text = "No hay ningún fichero activo"
End If
'' ------
'' encender el timer
'TimerUnSegundo.Start()
'' ------
' Obligar al CommandManager a generar el evento RequerySuggested
CommandManager.InvalidateRequerySuggested()
End Sub
'''
''' Destruir los objeto timer usados
'''
Private Sub DisposeTimer()
' detener los timer
Me.TimerUnSegundo.Stop()
' destruir los objetos timer usados
TimerUnSegundo = Nothing
End Sub
#End Region
End Class