superstar_v2/Services/MediaService.cs

151 lines
4.4 KiB
C#
Raw Normal View History

using System.IO;
2025-09-01 17:48:16 +08:00
// using DirectShowLib;
using LibVLCSharp;
namespace DualScreenDemo.Services
{
public class MediaService : IDisposable
{
private LibVLC _libVLC;
private MediaPlayer _mediaPlayer;
private Media? _media;
private bool _disposed;
2025-08-15 17:53:55 +08:00
public MediaService()
{
Core.Initialize();
_libVLC = new LibVLC(
2025-09-01 17:48:16 +08:00
// "--reset-plugins-cache", //產生libvlc plugins設定cache,加快初次啟動速度,生成快取後註解關閉此設定。
"--verbose=-1",
// enableDebugLogs: true,
"--audio-time-stretch",
"--vout=automatic",
"--h264-fps=30",
2025-08-15 12:15:33 +08:00
"--aout=directsound",
// "--network-caching=300",
// "--file-caching=300",
2025-08-15 17:53:55 +08:00
"--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)
{
2025-08-19 09:34:10 +08:00
try
{
_mediaPlayer.Hwnd = handle;
_mediaPlayer.AspectRatio = $"{width}:{height}";
_mediaPlayer.Scale = 0;
}
catch (Exception ex)
{
2025-08-19 09:34:10 +08:00
Console.WriteLine(ex.Message);
Program.WriteLog(ex.ToString());
2025-08-19 09:34:10 +08:00
}
}
#endregion
#region Playback
public MediaPlayer Player => _mediaPlayer;
public bool IsPlaying => _mediaPlayer.IsPlaying;
2025-08-19 09:34:10 +08:00
public bool IsAtEnd()
{
if (_mediaPlayer.State == VLCState.Stopped)
{
return true;
}
return false;
}
2025-09-01 17:48:16 +08:00
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)
{
2025-08-19 09:34:10 +08:00
try
{
_mediaPlayer.Stop();
2025-08-19 09:34:10 +08:00
_media?.Dispose();
_media = new Media(filePath, FromType.FromPath);
_mediaPlayer.Media = addMediaOption(_media, audioTrackIndex);
_mediaPlayer.Play();
2025-09-01 17:48:16 +08:00
_mediaPlayer.Fullscreen = true;
_mediaPlayer.Mute = false;
// _mediaPlayer.Stopped += (s, e) => Console.WriteLine("Player Stopped");
2025-08-19 09:34:10 +08:00
}
catch (Exception ex)
{
2025-08-19 09:34:10 +08:00
Console.WriteLine(ex.Message);
Program.WriteLog(ex.ToString());
2025-08-19 09:34:10 +08:00
}
}
2025-08-15 17:53:55 +08:00
2025-08-25 09:27:39 +08:00
private Media addMediaOption(Media media, int audioTrackIndex)
{
media.AddOption(":avcodec-hw=dxva2");
media.AddOption(":audio-output=directsound");
2025-09-01 17:48:16 +08:00
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}");
2025-08-25 09:27:39 +08:00
return media;
}
2025-08-15 17:53:55 +08:00
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;
}
2025-09-01 17:48:16 +08:00
#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;
}
2025-09-01 17:48:16 +08:00
}