ImageTracking_Video¶
演示平面图像跟踪功能以及在识别图上显示视频的功能。
演示如何使用Unity VideoPlayer加载并在target上播放视频
演示如何使用Unity VideoPlayer加载视频,用自定义shader实现透明视频播放
演示如何修改视频 aspect ratio (Unity VideoPlayer 功能) 适配image target
用法¶
详解¶
Play video¶
在这个 sample中,我们使用 Unity Video Player 来在target 图像上显示视频。
需注意的时,包含 VideoPlayerAgent 在内,这个sample中的所有脚本都是专为这个sample而写的代码。任何关于视频播放功能本身的需求都是一个Unity工程开发本身的问题。
VideoPlayerAgent 不是必须的。你可以用自己的方式来使用 Unity VideoPlayer 。这个sample设置了 VideoPlayer.source 及 VideoPlayer.url 来播放视频。
player.source = VideoSource.Url;
player.url = FileUtil.PathToUrl(path);
通常将视频放在 resources中会更方便,我们将视频文件放在 StreamingAssets中来确保兼容性,因为某些版本的Unity如果资源中有视频文件,Unity会有不正常的行为。
这个sample中还有另一个 Unity bug 的workaround,这个问题在 这篇文章 中也有所讨论。这个 workaround 将会使用网络视频来替代本地文件,视频播放速度可能会变慢。如果你使用的 Unity 版本已经修复了这个问题,可以安全地删除sample中相关代码。
通过target事件控制视频播放¶
在这个sample中,通过target事件处理中的代码,视频会在target被发现时开始播放,丢失的时候暂停播放。
private void Start()
{
...
controller.TargetFound += () =>
{
...
found = true;
StatusChanged();
};
controller.TargetLost += () =>
{
found = false;
StatusChanged();
};
}
private void StatusChanged()
{
...
if (found)
{
...
player.Play();
}
else
{
...
player.Pause();
}
}
视频的 mesh 会在视频数据未准备好或视频没有 prepareCompleted 的时候隐藏,以确保显示出来的 mesh 始终包含视频数据。
在target丢失的时候,这个mesh也会隐藏。
private void Start()
{
...
player.prepareCompleted += (source) =>
{
prepared = true;
StatusChanged();
};
}
private void StatusChanged()
{
if (!ready)
{
meshRenderer.enabled = false;
return;
}
if (found)
{
meshRenderer.enabled = prepared;
}
else
{
meshRenderer.enabled = false;
}
}
transform scale被调整为与target区域一致,以确保视频显示不超出图像target区域。
transform.localScale = new Vector3(1, 1 / controller.Target.aspectRatio(), 1);
视频云图像对齐的不同方式¶
视频如何与图像对齐(fit inside 或 stretch or 其它)可以由 VideoPlayer.aspectRatio 控制。这是 Unity VideoPlayer 本身的能力。
side-by-side 格式的透明视频¶
这里的透明视频是一种特殊类型的视频。它使用通常被3D视频所使用的 side-by-side 方式,左侧是彩色视频,右侧当做左侧的透明通道来使用。
视频本身没有特殊设置,使用了普通的视频编码和封装。创建这样的视频,值需要将视频宽度翻倍,并使用任何可行的工具将右侧视频的每个像素值按需设置为左侧的alpha值。
在Unity中使用这个视频唯一的不同是材质。
shader会重新计算像素值,将左侧和右侧合并到一起。
fixed4 frag(v2f i) : SV_Target
{
fixed4 color_a = tex2D(_MainTex, float2(i.uv.x / 2 + 0.5, i.uv.y));
fixed4 color_rgb = tex2D(_MainTex, float2(i.uv.x / 2, i.uv.y));
return fixed4(color_rgb.rgb, color_a.r);
}
Unity中的输出将会类似下面这样,其中黑色部分会是透明的。