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