163 lines
7.7 KiB
C#
163 lines
7.7 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|