ImageTracking_Video

演示平面图像跟踪功能以及在识别图上显示视频的功能。

  • 演示如何使用Unity VideoPlayer加载并在target上播放视频

  • 演示如何使用Unity VideoPlayer加载视频,用自定义shader实现透明视频播放

  • 演示如何修改视频 aspect ratio (Unity VideoPlayer 功能) 适配image target

用法

../../_images/image_271.png
标记1:显示系统状态和操作提示。
标记2:切换Video显示填充比例。

详解

Play video

../../_images/image_s2_1.png

在这个 sample中,我们使用 Unity Video Player 来在target 图像上显示视频。

需注意的时,包含 VideoPlayerAgent 在内,这个sample中的所有脚本都是专为这个sample而写的代码。任何关于视频播放功能本身的需求都是一个Unity工程开发本身的问题。

VideoPlayerAgent 不是必须的。你可以用自己的方式来使用 Unity VideoPlayer 。这个sample设置了 VideoPlayer.sourceVideoPlayer.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 方式,左侧是彩色视频,右侧当做左侧的透明通道来使用。

../../_images/image_s2_3.png

视频本身没有特殊设置,使用了普通的视频编码和封装。创建这样的视频,值需要将视频宽度翻倍,并使用任何可行的工具将右侧视频的每个像素值按需设置为左侧的alpha值。

在Unity中使用这个视频唯一的不同是材质。

../../_images/image_s2_2.png

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中的输出将会类似下面这样,其中黑色部分会是透明的。

../../_images/image_s2_4.png