using System.IO; // using DirectShowLib; using LibVLCSharp; 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( // "--reset-plugins-cache", //產生libvlc plugins設定cache,加快初次啟動速度,生成快取後註解關閉此設定。 "--verbose=-1", // enableDebugLogs: true, "--audio-time-stretch", "--vout=automatic", "--h264-fps=30", "--aout=directsound", // "--network-caching=300", // "--file-caching=300", "--audio-time-stretch" ); // _libVLC.Log += (sender, args) => // { // Console.WriteLine($"[{args.Level}] {args.Message}"); // }; _mediaPlayer = new MediaPlayer(_libVLC); _mediaPlayer.AspectRatio = "16:9"; _mediaPlayer.EnableHardwareDecoding = true; } #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); Program.WriteLog(ex.ToString()); } } #endregion #region Playback public MediaPlayer Player => _mediaPlayer; public bool IsPlaying => _mediaPlayer.IsPlaying; public bool IsAtEnd() { if (_mediaPlayer.State == VLCState.Stopped) { return true; } return false; } public bool IsAtEndTime() { var duration = _mediaPlayer.Media?.Duration ?? 0; var time = _mediaPlayer.Time; return duration > 0 && Math.Abs(duration - time) < 1000; } public void LoadMedia(string filePath, int audioTrackIndex = 0) { try { _mediaPlayer.Stop(); _media?.Dispose(); _media = new Media(filePath, FromType.FromPath); _mediaPlayer.Media = addMediaOption(_media, audioTrackIndex); _mediaPlayer.Play(); _mediaPlayer.Fullscreen = true; _mediaPlayer.Mute = false; // _mediaPlayer.Stopped += (s, e) => Console.WriteLine("Player Stopped"); } catch (Exception ex) { Console.WriteLine(ex.Message); Program.WriteLog(ex.ToString()); } } private Media addMediaOption(Media media, int audioTrackIndex) { media.AddOption(":avcodec-hw=dxva2"); media.AddOption(":audio-output=directsound"); media.AddOption(":drop-late-frames"); media.AddOption(":network-caching=300"); media.AddOption(":live-caching=300"); media.AddOption(":file-caching=300"); // media.AddOption(":clock-jitter=0"); // media.AddOption(":clock-synchro=0"); media.AddOption($":audio-track={audioTrackIndex}"); return media; } public void Play() => _mediaPlayer.Play(); public void Pause() => _mediaPlayer.Pause(); public void Stop() => _mediaPlayer.Stop(); #endregion #region Volume public void SetVolume(int volume) => _mediaPlayer.SetVolume(volume); public int GetVolume() => _mediaPlayer.Volume; public bool Mute(bool isMuted) { _mediaPlayer.Mute = isMuted; return _mediaPlayer.Mute; } #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; } }