This commit is contained in:
2026-02-12 22:15:15 +08:00
parent 47a5cff08b
commit 502c6efedc
58 changed files with 2114 additions and 708 deletions

View File

@@ -3,190 +3,225 @@ using System.Collections.Generic;
using NBC;
using RenderHeads.Media.AVProVideo;
using UnityEngine;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
namespace NBF
{
public class VideoManager : MonoBehaviour
{
[SerializeField] private MediaPlayer _mediaPlayer;
public static VideoManager Instance { get; private set; }
public ResolveToRenderTexture ResolveToRenderTexture;
public RenderTexture NowRT;
public Action<RenderTexture> OnPlayStart;
public Action<MediaPlayerEvent.EventType> OnHandleEvent;
private int _nowPlayUrlIndex = 0;
public float PlayProgress { get; private set; } = 0f;
private List<string> _urls = new List<string>()
{
"http://10.10.0.158:9888/files/video/1.mp4",
"http://10.10.0.158:9888/files/video/2.mp4",
"http://10.10.0.158:9888/files/video/3.mp4",
};
public GameObject prefab;
/// <summary>
/// 闲置的播放器
/// </summary>
private readonly Queue<VideoPlayerComponent> _idlePlayers = new Queue<VideoPlayerComponent>();
/// <summary>
/// 使用中的播放器
/// </summary>
private readonly List<VideoPlayerComponent> _usePlayers = new List<VideoPlayerComponent>();
private void Awake()
{
Instance = this;
_mediaPlayer.Events.AddListener(HandleEvent);
// Start adaptive stream using the highest resolution - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.startWithHighestBitrate = true;
// Set the maximum adaptive resolution to 1080p - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.preferredMaximumResolution =
MediaPlayer.OptionsAndroid.Resolution._1080p;
// // Set the peak adaptive bitrate to 4Mbps - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.preferredPeakBitRate = 4.0f;
// _mediaPlayer.PlatformOptionsAndroid.preferredPeakBitRateUnits =
// MediaPlayer.OptionsAndroid.BitRateUnits.Mbps;
}
private void Update()
/// <summary>
/// 获取一个播放器
/// </summary>
/// <returns></returns>
public VideoPlayerComponent GetPlayer(int videoIndex)
{
if (!_mediaPlayer) return;
if (_mediaPlayer.Info != null)
var ret = _usePlayers.Find(t => t.VideoIndex == videoIndex);
if (ret == null)
{
TimeRange timelineRange = GetTimelineRange();
double t = 0.0;
if (timelineRange.duration > 0.0)
{
t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
}
PlayProgress = Mathf.Clamp01((float)t);
var playerObject = Instantiate(prefab, transform);
ret = playerObject.GetComponent<VideoPlayerComponent>();
_usePlayers.Add(ret);
}
return ret;
}
#region
void HandleEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code)
/// <summary>
/// 返回一个播放器
/// </summary>
public void ReturnPlayer(int nowVideoIndex)
{
Debug.Log("MediaPlayer " + mp.name + " generated event: " + eventType.ToString());
OnHandleEvent?.Invoke(eventType);
if (eventType == MediaPlayerEvent.EventType.Error)
// _usePlayers.Remove(player);
// _idlePlayers.Enqueue(player);
List<VideoPlayerComponent> needRemove = new List<VideoPlayerComponent>();
foreach (var videoPlayerComponent in _usePlayers)
{
Debug.LogError("Error: " + code);
}
else if (eventType == MediaPlayerEvent.EventType.MetaDataReady)
{
Log.Info("播放数据已准备====");
}
else if (eventType == MediaPlayerEvent.EventType.Started)
{
var width = mp.Info.GetVideoWidth();
var height = mp.Info.GetVideoHeight();
Log.Info("播放开始====");
if (NowRT != null)
var offset = Math.Abs(videoPlayerComponent.VideoIndex - nowVideoIndex);
if (offset > 1)
{
NowRT.Release();
}
NowRT = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
ResolveToRenderTexture.ExternalTexture = NowRT;
OnPlayStart?.Invoke(NowRT);
}
}
#endregion
#region
public void TogglePlayPause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_mediaPlayer.Control.IsPlaying())
{
Pause();
}
else
{
Play();
videoPlayerComponent.CloseMedia();
needRemove.Add(videoPlayerComponent);
}
}
}
public void Play()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
foreach (var videoPlayerComponent in needRemove)
{
_mediaPlayer.Play();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.NeverSleep;
#endif
_usePlayers.Remove(videoPlayerComponent);
Destroy(videoPlayerComponent.gameObject);
}
}
private void Pause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_mediaPlayer.Pause();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.SystemSetting;
#endif
}
}
#endregion
private TimeRange GetTimelineRange()
{
if (_mediaPlayer.Info != null)
{
return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(),
_mediaPlayer.Control.GetSeekableTimes());
}
return new TimeRange();
}
public void Next()
{
if (_nowPlayUrlIndex >= _urls.Count - 1)
{
_nowPlayUrlIndex = 0;
}
else
{
_nowPlayUrlIndex++;
}
ChangeVideo();
}
public void Previous()
{
if (_nowPlayUrlIndex <= 0)
{
_nowPlayUrlIndex = _urls.Count - 1;
}
else
{
_nowPlayUrlIndex--;
}
ChangeVideo();
}
public void ChangeVideo()
{
_mediaPlayer.CloseMedia();
_mediaPlayer.SetMediaPath(new MediaPath(_urls[_nowPlayUrlIndex], MediaPathType.AbsolutePathOrURL));
_mediaPlayer.OpenMedia();
}
}
// {
// [SerializeField] private MediaPlayer _mediaPlayer;
//
// public static VideoManager Instance { get; private set; }
//
// public ResolveToRenderTexture ResolveToRenderTexture;
//
// public RenderTexture NowRT;
//
// public Action<RenderTexture> OnPlayStart;
// public Action<MediaPlayerEvent.EventType> OnHandleEvent;
//
// public float PlayProgress { get; private set; } = 0f;
//
//
// public bool IsPlaying =>
// _mediaPlayer != null && _mediaPlayer.Control != null && _mediaPlayer.Control.IsPlaying();
//
// private void Awake()
// {
// Instance = this;
//
// DontDestroyOnLoad(gameObject);
//
// _mediaPlayer.Events.AddListener(HandleEvent);
//
// // Start adaptive stream using the highest resolution - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.startWithHighestBitrate = true;
//
// // Set the maximum adaptive resolution to 1080p - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.preferredMaximumResolution =
// MediaPlayer.OptionsAndroid.Resolution._1080p;
// }
//
// private void Update()
// {
// if (!_mediaPlayer) return;
//
// if (_mediaPlayer.Info != null)
// {
// TimeRange timelineRange = GetTimelineRange();
// double t = 0.0;
// if (timelineRange.duration > 0.0)
// {
// t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
// }
//
// PlayProgress = Mathf.Clamp01((float)t);
// }
// }
//
// #region 事件
//
// void HandleEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code)
// {
// Debug.Log("MediaPlayer " + mp.name + " generated event: " + eventType.ToString());
// OnHandleEvent?.Invoke(eventType);
// if (eventType == MediaPlayerEvent.EventType.Error)
// {
// Debug.LogError("Error: " + code);
// }
// else if (eventType == MediaPlayerEvent.EventType.MetaDataReady)
// {
// Log.Info("播放数据已准备====");
// }
// else if (eventType == MediaPlayerEvent.EventType.Started)
// {
// var width = mp.Info.GetVideoWidth();
// var height = mp.Info.GetVideoHeight();
// Log.Info("播放开始====");
// if (NowRT != null)
// {
// NowRT.Release();
// }
//
// NowRT = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
//
// ResolveToRenderTexture.ExternalTexture = NowRT;
// OnPlayStart?.Invoke(NowRT);
// }
// }
//
// #endregion
//
// #region 播放控制
//
// public void TogglePlayPause()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// if (_mediaPlayer.Control.IsPlaying())
// {
// Pause();
// }
// else
// {
// Play();
// }
// }
// }
//
// public void Play()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// _mediaPlayer.Play();
//
// #if UNITY_ANDROID || UNITY_OPENHARMONY
// Screen.sleepTimeout = SleepTimeout.NeverSleep;
// #endif
// }
// }
//
// public void Pause()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// _mediaPlayer.Pause();
// #if UNITY_ANDROID || UNITY_OPENHARMONY
// Screen.sleepTimeout = SleepTimeout.SystemSetting;
// #endif
// }
// }
//
// #endregion
//
//
// private TimeRange GetTimelineRange()
// {
// if (_mediaPlayer.Info != null)
// {
// return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(),
// _mediaPlayer.Control.GetSeekableTimes());
// }
//
// return new TimeRange();
// }
//
//
// public void ChangeVideo(string url)
// {
// _mediaPlayer.CloseMedia();
// _mediaPlayer.SetMediaPath(new MediaPath(url, MediaPathType.AbsolutePathOrURL));
// _mediaPlayer.OpenMedia();
// }
// }
}