using LibVLCSharp.Shared; namespace DualScreenDemo.Services { public class MediaService : IDisposable { private LibVLC _libVLC; private MediaPlayer _mediaPlayer; private Media? _media; private bool _disposed; public MediaService() { Core.Initialize(); _libVLC = new LibVLC( // "--verbose=2", "--audio-time-stretch", // "--vout=automatic", "--h264-fps=30", "--aout=directsound", "--network-caching=250", "--file-caching=250", "--audio-time-stretch" ); _mediaPlayer = new MediaPlayer(_libVLC); } #region Player Setup public void SetVideoOutput(nint handle, int width, int height) { try { _mediaPlayer.Hwnd = handle; _mediaPlayer.AspectRatio = $"{width}:{height}"; _mediaPlayer.Scale = 0; } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion #region Playback public MediaPlayer Player => _mediaPlayer; public bool IsPlaying => _mediaPlayer.IsPlaying; // public bool IsAtEnd() // { // try // { // _mediaPlayer.EndReached += (sender, args) => { }; // var duration = _mediaPlayer.Media?.Duration ?? 0; // var time = _mediaPlayer.Time; // return duration > 0 && Math.Abs(duration - time) < 1000; // } // catch (Exception ex) // { // Console.WriteLine(ex.Message); // return true; // } // } public bool IsAtEnd() { if (_mediaPlayer.State == VLCState.Ended) { return true; } return false; } public void LoadMedia(string filePath, int audioTrackIndex = 0) { try { // Console.WriteLine($"LoadMedia. in"); // _media?.ParseStop(); // Console.WriteLine($"LoadMedia. ParseStop"); _mediaPlayer.Stop(); // Console.WriteLine($"LoadMedia. Stop"); _media?.Dispose(); // Console.WriteLine($"LoadMedia. Dispose"); _media = new Media(_libVLC, filePath, FromType.FromPath); _media.AddOption(":avcodec-hw=dxva2"); _media.AddOption(":vout=gl"); _media.AddOption(":audio-output=directsound"); _media.AddOption($":audio-track={audioTrackIndex}"); // _media.AddOption(":start-time=0.5"); _mediaPlayer.Media = _media; _mediaPlayer.Play(_media); } catch (Exception ex) { Console.WriteLine(ex.Message); } } public void Play() => _mediaPlayer.Play(); public void Pause() => _mediaPlayer.Pause(); public void Stop() => _mediaPlayer.Stop(); #endregion #region Audio public List GetAudioTracks() { var result = new List(); var media = _mediaPlayer.Media; if (media == null) return result; if (!media.IsParsed) media.Parse(MediaParseOptions.ParseLocal); var tracks = media.Tracks; if (tracks == null) return result; foreach (var track in tracks.Where(t => t.TrackType == TrackType.Audio)) { result.Add(new TrackDescription { Id = track.Id, Name = !string.IsNullOrEmpty(track.Language) ? track.Language : $"Audio Track {track.Id}" }); } return result; } public void SetAudioTrack(int trackIndex) { var audioTracks = GetAudioTracks(); if (trackIndex < 0 || trackIndex >= audioTracks.Count) return; _mediaPlayer.SetAudioTrack(audioTracks[trackIndex].Id); } #endregion #region Volume public void SetVolume(int volume) => _mediaPlayer.Volume = volume; public int GetVolume() => _mediaPlayer.Volume; public bool Mute(bool isMuted) => _mediaPlayer.Mute = isMuted; #endregion #region Dispose public void Dispose() { if (_disposed) return; _mediaPlayer.Dispose(); _media?.Dispose(); _libVLC.Dispose(); _media = null; _disposed = true; } #endregion } public class TrackDescription { public int Id { get; set; } public string Name { get; set; } = string.Empty; } }