superstar_v2/Services/MediaService.cs
jasonchenwork 7d71e85d57 2508191749
撥放器參數調整
媒體播畢邏輯判斷更改
系統公告顏色改回紅色
2025-08-19 17:50:37 +08:00

169 lines
4.9 KiB
C#

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<TrackDescription> GetAudioTracks()
{
var result = new List<TrackDescription>();
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;
}
}