Disclaimer: I am writing this post about the video player in it’s current state within the current beta version Unity 5.6.0b9 which was released: February 17, 2017
The long awaited replacement for Unity’s now legacy Movie Texture is here and comes in the form of a newly written Video Playback solution. This post will tell you all about it, how to use it, what features it contains and some general tips and tricks. If you have any questions which aren’t answered in this post feel free to write in the comments section and I’ll get back to you asap.
The Video Player is a new component that you add to game objects for movie playback in your scene. The Video Player will use the native video hardware capabilities of both the editor and target platforms.
Playback Source:
The first thing you might notice from the screenshot above is the Source is currently set to Video Clip, you can define the clip by dragging and dropping the clip into the property. The Video Player can play movies that were imported with the new Video Clip importer or it can read movies from Streaming Assets, local files or http sources using progressive streaming:
Render Mode:
The component also contains a Render Mode property where currently there are five options, but perhaps some of the more exciting options is the ability to render a video through a Material Override option as well as a Render Texture.
Material Override:
This option allows for a texture parameter in the current object renderer’s material to be used for receiving the video. If we take a 360 video example as a use case, you would use Material Override to ensure the video is being wrapped around a spheres mesh, I use a shader to invert the normals:
Shader "Custom/Mobile/Invert Normals" { Properties { [NoScaleOffset]_MainTex ("Texture (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } Cull Front Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = float2(v.uv.x, v.uv.y); v.normal = v.normal * -1; return o; } fixed4 frag (v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } }
If we were to use Unity’s Standard shader as a Material Override option, we then gain access to the available texture slots for that shader:
Just think about those possibilities for a second; do you now have the idea of animating a bump map with a movie? You could write a custom shader that deforms a mesh using one of the texture inputs. My example below is using a custom Holographic shader to render the movie clip in an interesting way:
Shaders are incredibly powerful scripts and empower us to render things in interesting ways, it’s awesome we can apply custom shaders to the Video Player, opens up for some interesting possibilities.
Video Codecs:
The Video Player component aims at using h.264 and VP8 for hardware which are supported on a wide variety of platforms. On the audio side we have AAC and Vorbis. If you are looking for the alpha channel to be respected within a movie clip you need to utilise ProRes 4444 which is a lossy video compression format developed by Apple Inc.
Audio:
A slight complication comes with Audio here which I felt was worth mentioning; On OS X which has the most desirable workflow at present (arguably), you can chose the Audio Output Mode to be Direct, what this does is play back the Audio which is already embedded from within the movie clip. On Windows Direct Audio Output Mode does not work as it is only supported on Apple platforms, for OS X and iOS you are okay but non-Apple platforms you need to revert to the Audio Source option, this allows you to define the Audio file you want to have play back with the video. Since both the Movie clip and Audio clip are decoded from the same stream we shouldn’t see any issues with synchronisation.
Scripting:
The Video Player class can be found within its own namespace UnityEngine.Video. The documentation for this is extensive but I did want to highlight a specific API which I think is a very useful feature. video.IsPrepared; This API checks whether the player has successfully prepared the content to be played back. When the content is prepared the player can start playing back the associated content instantly, the API is especially important when you are using the Streaming Assets, local files or http sources, this short scripting example will demonstrate the video.prepareCompleted; function to ensure the content is ready to playback from a HTTP source:
using UnityEngine; using UnityEngine.Video; public class HTTPVideoScript : MonoBehaviour { // Use this for initialization void Start () { var vPlayer = gameObject.AddComponent<UnityEngine.Video.VideoPlayer>(); vPlayer.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"; vPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraFarPlane; vPlayer.targetCameraAlpha = 0.5f; vPlayer.prepareCompleted += Prepared; vPlayer.Prepare(); } void Prepared(UnityEngine.Video.VideoPlayer vPlayer) { Debug.Log("End reached!"); vPlayer.Play(); } }
That’s it folks, I hope this proves useful in your adoption of Unity 5.6 and importantly the new Video Player component, I’ll leave this with you as a thanks for scrolling all the way to the bottom 🙂