Saltar al contenido
Ricardo RetamalSoftware y cosas que vale la pena construir
/
Conversemos
← Ver todos los escritos
Software3 min read

Cómo Integrar LibVLCSharp en .NET MAUI

En otros artículos he revisado como integrar algunas librerías RTSP para visualización de cámaras en aplicaciones móviles, el día de hoy…

Publicado originalmente en Medium ↗

En otros artículos he revisado como integrar algunas librerías RTSP para visualización de cámaras en aplicaciones móviles, el día de hoy revisaremos como integrar la librería LibVLCSharp en .Net MAUI que nos ayudará tanto a reproducir el stream de cámara IP como cualquier otro contenido multimedia.

En este proyecto cubriremos lo siguiente:

  • Creación del proyecto
  • Instalación de la librería
  • Creación de un view para reproducir el contenido
  • Creación de los handlers para manejar el contenido en Android y iOS

Lo primero que tendremos que hacer es crear un nuevo proyecto en Visual Studio 2022:

Seguidamente tendremos que asignarle un nombre, en mi caso le puse MauiVlc:

Y seguidamente el framework que queremos usar en el proyecto:

Ya una vez cumplido ese paso nuestro proyecto se debe ver de la siguiente manera:

¿Qué tenemos que hacer ahora? Instalar las librerías! para ellos haras click derecho en el proyecto e iras a nuget para buscar la librería VideoLAN.LibVLC.Android y VideoLAN.LibVLC.iOS y si, tienes que instalarlas en el mismo proyecto.

Ya una vez que tenemos las librerías crearemos una carpeta “Controls” en un nuestro proyecto y le agregaremos una clase MediaViewer. El proyecto debería estar viéndose de la siguiente manera:

Y clase MediaViewer debería quedar de la siguiente manera:

public class MediaViewer : View
	{
        public static BindableProperty VideoUrlProperty = BindableProperty.Create(nameof(VideoUrl)
           , typeof(string)
           , typeof(MediaViewer)
           , ""
           , defaultBindingMode: BindingMode.TwoWay);


        public string VideoUrl
        {
            get => (string)GetValue(VideoUrlProperty);
            set => SetValue(VideoUrlProperty, value);
        }


    public MediaViewer()
		{
		}
	}

GitHub Gist ↗

La clase como podrás ver hereda de View e implementa una propiedad VideoUrl para poder indicar la ruta del video que queremos mostrar.

El siguiente paso es crear la carpeta Handlers donde guardaremos los handlers respectivos para el uso de la librería de VLC:

El MediaViewerHandler se verá de la siguiente manera:

public partial class MediaViewerHandler
	{
        public static IPropertyMapper<MediaViewer, MediaViewerHandler> PropertyMapper = 
                                new PropertyMapper<MediaViewer, MediaViewerHandler>()
        {
        };


        public static CommandMapper<MediaViewer, MediaViewerHandler> CommandMapper = new(ViewCommandMapper)
        {
        };


        public MediaViewerHandler() : base(PropertyMapper, CommandMapper)
        {
		}
	}

GitHub Gist ↗

La implementación para Android se verá así:

public partial class MediaViewerHandler: ViewHandler<MediaViewer, VideoView>
    {
        VideoView _videoView;
        LibVLC _libVLC;
        LibVLCSharp.Shared.MediaPlayer _mediaPlayer;


        protected override VideoView CreatePlatformView() => new VideoView(Context);


        protected override void ConnectHandler(VideoView nativeView)
        {
            base.ConnectHandler(nativeView);


            _libVLC = new LibVLC(enableDebugLogs: true);
            _mediaPlayer = new LibVLCSharp.Shared.MediaPlayer(_libVLC)
            {
                EnableHardwareDecoding = true
            };


            _videoView = nativeView ?? new VideoView(Context);
            _videoView.MediaPlayer = _mediaPlayer;


            HandleUrl(VirtualView.VideoUrl);


            base.ConnectHandler(nativeView);
        }


        protected override void DisconnectHandler(VideoView nativeView)
        {
            nativeView.Dispose();
            base.DisconnectHandler(nativeView);
        }


        private void HandleUrl(string url)
        {
            try
            {


                if (url.EndsWith("/"))
                {
                    url = url.TrimEnd('/');
                }


                //url = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";


                if (!string.IsNullOrEmpty(url))
                {
                    var media = new Media(_libVLC, url, FromType.FromLocation);


                    _mediaPlayer.NetworkCaching = 1500;


                    if (_mediaPlayer.Media != null)
                    {
                        _mediaPlayer.Stop();
                        _mediaPlayer.Media.Dispose();
                    }


                    _mediaPlayer.Media = media;
                    _mediaPlayer.Mute = true;


                    _videoView.MediaPlayer.Play();
                }
            }
            catch (Exception ex)
            {
            }
        }


    }

GitHub Gist ↗

public partial class MediaViewerHandler : ViewHandler<MediaViewer, VideoView>
    {
        VideoView _videoView;
        LibVLC _libVLC;
        LibVLCSharp.Shared.MediaPlayer _mediaPlayer;


        protected override VideoView CreatePlatformView()
        {
            return new VideoView();
        }


        protected override void ConnectHandler(VideoView nativeView)
        {
            base.ConnectHandler(nativeView);


            Core.Initialize();


            _libVLC = new LibVLC(enableDebugLogs: true);
            _mediaPlayer = new LibVLCSharp.Shared.MediaPlayer(_libVLC)
            {
                EnableHardwareDecoding = true
            };


            _videoView = nativeView ?? new VideoView();
            _videoView.MediaPlayer = _mediaPlayer;


            HandleUrl(VirtualView.VideoUrl);
        }


        protected override void DisconnectHandler(VideoView nativeView)
        {
            nativeView.Dispose();
            base.DisconnectHandler(nativeView);
        }


        public void HandleUrl(string url)
        {
            try
            {
                if (url.EndsWith("/"))
                {
                    url = url.TrimEnd('/');
                }


                if (!string.IsNullOrEmpty(url))
                {
                    var media = new Media(_libVLC, url, FromType.FromLocation);


                    _mediaPlayer.NetworkCaching = 1500;


                    if (_mediaPlayer.Media != null)
                    {
                        _mediaPlayer.Stop();
                        _mediaPlayer.Media.Dispose();
                    }


                    _mediaPlayer.Media = media;
                    _mediaPlayer.Mute = true;


                    _videoView.MediaPlayer.Play();
                }
            }
            catch (Exception ex)
            {
                // Handle exception
            }
        }
    }

GitHub Gist ↗

Ya una vez cumplidos esos pasos lo que queda es registrar el handler en el archivo MauiProgram.cs:

public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                             .ConfigureMauiHandlers((handlers) => {
                                 handlers.AddHandler(typeof(MediaViewer), typeof(MauiVlc.Handlers.MediaViewerHandler));
                             })
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });


#if DEBUG
    		builder.Logging.AddDebug();
#endif


            return builder.Build();
        }
    }

GitHub Gist ↗

Si quieres ver el código lo puedes ver en el repositorio de GitHub:

rretamal/MauiVLC (github.com)

Si quieres ver un ejemplo funcionando puedes descargarte la app de ejemplo aquí:

Android:

ReCam Viewer — Apps on Google Play

Happy Coding!

https://www.buymeacoffee.com/2hepU6W