using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Assets.AR { public class VideoPlayerControl { private const float MinVideoPlaybackSpeedChangeInterval = 0.2f; private const float MaxPlaybackSpeed = 1.5f; private const float MaxCameraDistanceError = 200f; private DateTime lastPlaybackSpeedChange = DateTime.MinValue; private float fixedTimeFrame; private DateTime fixedTimeSeekFinished = DateTime.MinValue; private int lapCount = 1; private double lapLength; public float FixedVideoFrame => this.fixedTimeFrame; //public IDistanceSource RiderDistance { get; set; public AVProVideoPlayer VideoPlayer { get; private set; } //public ISpeedSource RiderSpeed { get; set; } public VideoPointsSync VideoSyncSource { get; set; } public ARRoute Route { get; set; } public int VideoFrameOffset { get; set; } public float CameraFollowDistance { get; set; } public bool AllowUpdate { get; set; } = true; public float CameraDistanceError { get; private set; } public bool IsTimeFixed { get; private set; } public float FrameIndexDistanceCorrection { get; private set; } public bool IsMultilap => this.lapCount > 1; public void SetVideoPlayer(AVProVideoPlayer player) => this.VideoPlayer = player; public void SetMultiLap(int lapCount, double lapLength) { this.lapCount = lapCount; this.lapLength = lapLength; } public void FixTimeByDistance(float distance) => this.FixTimeByFrame(this.VideoSyncSource.GetVideoFrameAtDistance(distance)); public void FixTimeByFrame(float frame) { this.IsTimeFixed = true; this.fixedTimeFrame = frame; this.fixedTimeSeekFinished = DateTime.MinValue; if (this.VideoPlayer.IsPaused) this.VideoPlayer.Resume(); this.VideoPlayer.SetPlaybackSpeed(0.25f); this.VideoPlayer.Seek((long)frame, true); } //public void UnFixTime() //{ // this.IsTimeFixed = false; // float videoFrameAtDistance = this.VideoSyncSource.GetVideoFrameAtDistance(this.RiderDistance.LapDistance); // float num = this.VideoSyncSource.AverageVideoSpeed(videoFrameAtDistance, videoFrameAtDistance); // float playbackSpeed = (double)num != 0.0 ? this.RiderSpeed.Speed / num : 0.0f; // if (this.VideoPlayer.IsPaused) // this.VideoPlayer.Resume(); // this.VideoPlayer.SetPlaybackSpeed(playbackSpeed); // this.lastPlaybackSpeedChange = DateTime.UtcNow; // this.VideoPlayer.Seek((long)videoFrameAtDistance, true); //} private void SkipVideoToDistance(float distance) => this.SkipVideoToFrame((long)this.VideoSyncSource.GetVideoFrameAtDistance(distance)); private void SkipVideoToFrame(long frame) => this.VideoPlayer.Seek(frame); public void UpdateVideoPlaybackSpeed(float speed, float routeDistance) { if (!this.AllowUpdate) return; if (this.IsTimeFixed) { if (this.VideoPlayer.IsSeeking) return; if (this.fixedTimeSeekFinished == DateTime.MinValue) this.fixedTimeSeekFinished = DateTime.UtcNow; if (DateTime.UtcNow.Subtract(this.fixedTimeSeekFinished).TotalSeconds < 0.25) return; if ((double)this.VideoPlayer.CurrentFrame > (double)this.fixedTimeFrame) this.VideoPlayer.Pause(); this.VideoPlayer.UpdateCurrentFrame(); this.FrameIndexDistanceCorrection = 0.0f; } else { float videoFrameAtDistance1 = this.VideoSyncSource.GetVideoFrameAtDistance(routeDistance); float val2 = routeDistance - this.CameraFollowDistance; //if (this.IsMultilap && (double)this.RiderDistance.RouteDistance > (double)distance && (double)val2 < 0.0) // val2 += (float)this.lapLength; float distance = Math.Max(0.0f, val2); float frame = this.VideoSyncSource.GetVideoFrameAtDistance(distance) + (float)this.VideoFrameOffset; if (this.Route != null && (double)this.Route.GetVisibility(frame) > 10.0) frame = (float)this.Route.GetFrameAtDistance(Math.Max(0.0, this.Route.GetDistanceForFrame((double)videoFrameAtDistance1) - (double)this.CameraFollowDistance)) + (float)this.VideoFrameOffset; this.VideoPlayer.UpdateCurrentFrame(); float distanceForVideoFrame = this.VideoSyncSource.GetDistanceForVideoFrame(this.VideoPlayer.CurrentFrame - (float)this.VideoFrameOffset); float f; if (this.Route != null) { double frameAtDistance = this.Route.GetFrameAtDistance(this.Route.GetDistanceForFrame((double)this.VideoPlayer.CurrentFrame - (double)this.VideoFrameOffset) + (double)Mathf.Min(routeDistance, this.CameraFollowDistance)); f = videoFrameAtDistance1 - (float)frameAtDistance; } else f = frame - (this.VideoPlayer.CurrentFrame - (float)this.VideoFrameOffset); float num1 = Mathf.Clamp01(VTMath.Lerp(0.0f, 1f, 100f, 0.0f, Mathf.Abs(f))); this.FrameIndexDistanceCorrection = f * num1; this.CameraDistanceError = distance - distanceForVideoFrame; if (this.IsMultilap) { float num2 = distance - (distanceForVideoFrame + (float)this.lapLength); if ((double)Math.Abs(num2) < (double)Math.Abs(this.CameraDistanceError) && (double)Math.Abs(num2) < 200.0) return; } if ((double)Math.Abs(this.CameraDistanceError) > 200.0) { this.SkipVideoToDistance(distance); } else { double totalSeconds = DateTime.UtcNow.Subtract(this.lastPlaybackSpeedChange).TotalSeconds; if (totalSeconds >= 0.0 && totalSeconds < 0.20000000298023224) return; float num3 = 1f; float num4 = num3 * speed; if ((double)Math.Abs(distance + num4 - this.VideoSyncSource.GetDistanceForVideoFrame((float)((double)this.VideoPlayer.CurrentFrame - (double)this.VideoFrameOffset + (double)num3 * (double)this.VideoPlayer.PlaybackSpeed * (double)this.VideoPlayer.FrameRate))) <= (double)Math.Abs(this.CameraDistanceError)) return; float videoFrameAtDistance2 = this.VideoSyncSource.GetVideoFrameAtDistance(routeDistance + num4); float num5 = this.VideoSyncSource.AverageVideoSpeed(videoFrameAtDistance1, videoFrameAtDistance2); float playbackSpeed = Mathf.Clamp(((double)num5 != 0.0 ? speed / num5 : 0.0f) + (float)(((double)frame - ((double)this.VideoPlayer.CurrentFrame - (double)this.VideoFrameOffset)) / 2.0) / this.VideoPlayer.FrameRate, 0.0f, 1.5f); if ((double)playbackSpeed == (double)this.VideoPlayer.PlaybackSpeed || !this.VideoPlayer.SetPlaybackSpeed(playbackSpeed)) return; this.lastPlaybackSpeedChange = DateTime.UtcNow; } } } internal void UpdateVideoPlaybackSpeed(double speed, float distance) { throw new NotImplementedException(); } } }