当前位置:网站首页>Unity学习笔记 关于AVPro视频跳转功能(Seeking)的说明
Unity学习笔记 关于AVPro视频跳转功能(Seeking)的说明
2022-07-31 13:40:00 【Lawa0592】
1. Seeking功能的相关接口
通过双精度时间寻找跳转:
- Seek() ⇒ 跳转到精确的指定时间上的画面
- SeekFast() ⇒ 跳转到指定时间上最近的帧画面
- SeekWithTolerance() ⇒ 跳转到指定时间上某个范围时间内的画面(只支持macOS,ios,tvOS)
通过使用帧寻找跳转(只对具有已知恒定帧速率的媒体有效):
- SeekToFrame() ⇒ 跳转到具体某一帧的画面
- SeekToFrameRelative() ⇒ 跳转到相对于当前帧向前或向后多少帧的画面
底层接口源码如下:
/// <summary>
/// The time in seconds seeked will be to the exact time
/// This can take a long time is the keyframes are far apart
/// Some platforms don't support this and instead seek to the closest keyframe
/// </summary>
void Seek(double time);
/// <summary>
/// The time in seconds seeked will be to the closest keyframe
/// </summary>
void SeekFast(double time);
/// <summary>
/// The time in seconds seeked to will be within the range [time-timeDeltaBefore, time+timeDeltaAfter] for efficiency.
/// Only supported on macOS, iOS and tvOS.
/// Other platforms will automatically pass through to Seek()
/// </summary>
void SeekWithTolerance(double time, double timeDeltaBefore, double timeDeltaAfter);
/// <summary>
/// Seek to a specific frame, range is [0, GetMaxFrameNumber()]
/// NOTE: For best results the video should be encoded as keyframes only
/// and have no audio track, or an audio track with the same length as the video track
/// </summary>
void SeekToFrame(int frame, float overrideFrameRate = 0f);
/// <summary>
/// Seek forwards or backwards relative to the current frame
/// NOTE: For best results the video should be encoded as keyframes only
/// and have no audio track, or an audio track with the same length as the video track
/// </summary>
void SeekToFrameRelative(int frameOffset, float overrideFrameRate = 0f);
需要注意的是,跳转的响应/行为在不同平台会有不同差异
平台 | 快速近似关键帧搜索(Fast Approximate Keyframe Seeking) | 慢速精确寻帧(Slow Accurate Frame Seeking) |
---|---|---|
Windows (WinRT / Media Foundation) | * | * |
Windows (DirectShow) | * | 取决于编解码器 |
Android (ExoPlayer) | * | * |
Android (MediaPlayer) | * | API 26 及以上 |
macOS | * | * |
iOS/iPadOS/tvOS | * | * |
WebGL | * | 视情况而变化 |
2. 跳转(Seeking)功能的实现案例
具体的实现可以参考AVPro提供的Demo(Demo_MediaPlayer场景)
下面只列出结合时间条(slider)进行视频跳转的部分:
[Header("UI Components")]
[SerializeField] Slider _sliderTime = null;
void Start()
{
CreateTimelineDragEvents();
}
private void CreateTimelineDragEvents()
{
EventTrigger trigger = _sliderTime.gameObject.GetComponent<EventTrigger>();
if (trigger != null)
{
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerDown;
entry.callback.AddListener((data) => {
OnTimeSliderBeginDrag(); });
trigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Drag;
entry.callback.AddListener((data) => {
OnTimeSliderDrag(); });
trigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerUp;
entry.callback.AddListener((data) => {
OnTimeSliderEndDrag(); });
trigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerEnter;
entry.callback.AddListener((data) => {
OnTimelineBeginHover((PointerEventData)data); });
trigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerExit;
entry.callback.AddListener((data) => {
OnTimelineEndHover((PointerEventData)data); });
trigger.triggers.Add(entry);
}
}
private bool _wasPlayingBeforeTimelineDrag;
private void OnTimeSliderBeginDrag()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_wasPlayingBeforeTimelineDrag = _mediaPlayer.Control.IsPlaying();
if (_wasPlayingBeforeTimelineDrag)
{
_mediaPlayer.Pause();
}
OnTimeSliderDrag();
}
}
private void OnTimeSliderDrag()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
TimeRange timelineRange = GetTimelineRange();
double time = timelineRange.startTime + (_sliderTime.value * timelineRange.duration);
_mediaPlayer.Control.Seek(time);
_isHoveringOverTimeline = true;
}
}
private void OnTimeSliderEndDrag()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_wasPlayingBeforeTimelineDrag)
{
_mediaPlayer.Play();
_wasPlayingBeforeTimelineDrag = false;
}
}
}
private bool _isHoveringOverTimeline;
private void OnTimelineBeginHover(PointerEventData eventData)
{
if (eventData.pointerCurrentRaycast.gameObject != null)
{
_isHoveringOverTimeline = true;
_sliderTime.transform.localScale = new Vector3(1f, 2.5f, 1f);
}
}
private void OnTimelineEndHover(PointerEventData eventData)
{
_isHoveringOverTimeline = false;
_sliderTime.transform.localScale = new Vector3(1f, 1f, 1f);
}
参考文献
边栏推荐
- 六石编程学:不论是哪个功能,你觉得再没用,会用的人都离不了,所以至少要做到99%
- Productivity Tools and Plugins
- 模拟量差分和单端(iou计算方法)
- 知名无人驾驶公司:文远知行内推
- 自制的数据库安全攻防题,相关靶机自己制作
- [Niu Ke brush questions - SQL big factory interview questions] NO3. E-commerce scene (some east mall)
- 使用CompletableFuture进行异步处理业务
- 技能大赛训练题: 子网掩码划分案例
- Spark Learning: Add Custom Optimization Rules for Spark Sql
- Save and load numpy matrices and vectors, and use the saved vectors for similarity calculation
猜你喜欢
推荐系统-召回阶段-2013:DSSM(双塔模型)【Embedding(语义向量)召回】【微软】
The use of C# control CheckBox
深入浅出边缘云 | 4. 生命周期管理
ECCV 2022 | Robotic Interaction Perception and Object Manipulation
Even if the image is missing in a large area, it can also be repaired realistically. The new model CM-GAN takes into account the global structure and texture details
机器学习模型验证:被低估的重要一环
365-day challenge LeetCode1000 questions - Day 044 Maximum element in the layer and level traversal
[CPU Design Practice] Simple Pipeline CPU Design
Introduction to using NPM
Reasons and solutions for Invalid bound statement (not found)
随机推荐
EXCEL如何快速拆分合并单元格数据
IDEA如何运行web程序
All-round visual monitoring of the Istio microservice governance grid (microservice architecture display, resource monitoring, traffic monitoring, link monitoring)
Sliding window method to segment data
ECCV 2022 | Robotic Interaction Perception and Object Manipulation
JSP中如何借助response对象实现页面跳转呢?
Batch大小不一定是2的n次幂!ML资深学者最新结论
动作捕捉系统用于柔性机械臂的末端定位控制
「面经分享」西北大学 | 字节 生活服务 | 一面二面三面 HR 面
uniapp微信小程序引用标准版交易组件
C#控件 ToolStripProgressBar 用法
Error IDEA Terminated with exit code 1
Controller层代码这么写,简洁又优雅!
全局平均池化层替代全连接层(最大池化和平均池化的区别)
golang-gin-pprof-使用以及安全问题
Shell脚本经典案例:文件的备份
【牛客刷题-SQL大厂面试真题】NO3.电商场景(某东商城)
Flutter keyboard visibility
线程池的使用二
Hard disk partition, expand disk C, no reshipment system, not heavy D dish of software full tutorial.