using System; using System.Collections.Generic; using NBC; using RenderHeads.Media.AVProVideo; using UnityEngine; 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 OnPlayStart; public Action OnHandleEvent; private int _nowPlayUrlIndex = 0; public float PlayProgress { get; private set; } = 0f; private List _urls = new List() { "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", }; 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() { 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 } } 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(); } } }