Streaming Video Support

The GVR SDK for Unity includes an additional GVR video plugin that supports streaming flat and 360° videos in both mono and stereo formats by using the ExoPlayer library to handle decoding and rendering of video, audio, and related streams. ExoPlayer provides all the standard playback framework for both videos embedded in your application and streaming videos, including adaptive streaming support, such as DASH and HLS.

Configuring your video player

The GVR SDK for Unity provides a C# script, called GvrVideoPlayerTexture, that allows you to configure your video player. The script renders the video image into a texture created in Unity. The texture can then be placed on any mesh renderer in the scene.

To use the script, add it to a GameObject with a Mesh Renderer component. At runtime, the script creates another texture and uses that as the main texture of the renderer.

Player properties

The GvrVideoPlayerTexture script allows you to adjust the following properties:

  • Status Text: Allows you to put in a text component that can display textual information like framerate and resolution.
  • Buffer Size: Determines the buffer size, with a minimum value of 3 and a maximum value of 15.
  • Video Type: Determines the video type. The options are:
    • Dash
    • HLS
    • Other (used for local video)
  • Video URL: The video file's location.
  • Video Content ID: The video file's Content ID.
  • Video Provider ID: The video file's Provider ID.
  • Initial Resolution: The target resolution for the video. The options are:
    • Lowest (Sets the video to the lowest possible resolution.)
    • 720
    • 1080
    • 2048
    • Highest (Sets the video to the highest possible resolution.)
  • Adjust Aspect Ratio: If this box is checked, the size of the video player object will be adjusted to match the video's aspect ratio. Only applies to flat videos.

Examples

These examples demonstrate how to build a simple video player within VR.

Prerequisites

Setting up your scene

The following steps set up the Daydream controller support, which all the video player examples require.

  1. Create a new 3D Unity Project.
  2. Configure the build settings to enable Daydream support.
  3. Import the GVR SDK for Unity.
    1. Under the Assets menu, select Import Package, then Custom Package, then navigate to the Unity GVR SDK and select it.
  4. Import the VideoPlayer SDK.
    1. In the Project panel, find the GVRVideoPlayer package located in the GoogleVR folder. Double-click the package to import it.
  5. Enable support for the Daydream controller and UI.
    1. Add GvrEditorEmulator to the scene, located under GoogleVR/Prefabs.
    2. Add GvrControllerMain to the scene, located under GoogleVR/Prefabs/Controller.
    3. Add GvrControllerPointer, located under GoogleVR/Prefabs/UI.
    4. Add GvrReticlePointer, located under GoogleVR/Prefabs/UI.
    5. Create an empty game object and name it EventSystem. Add an Event System component, and then attach the GvrPointerInputModule script.

Flat Video

This example shows how to create a flat video playback using DASH with a video hosted on Google Cloud Storage.

  1. This example assumes you've run the steps in Setting up your scene.
  2. Configure the main camera.
    1. Set the Position to (0, 1, 0).
    2. Set Target Eye to both.
  3. Add the video player object.
    1. Create a Quad object (Game Object > 3D Object > Quad).
    2. Set the Position to (0,1,12)
    3. Set the Scale to (16,9,1) for a 16:9 aspect ratio.
  4. Add the video material to the video player object. This is what's shown until the video loads.
    1. In the Mesh Renderer component, expand Materials and set element 0 to be VideoMaterial, or StereoMaterial if the video is a stereoscopic video, located under GoogleVR/Demos/Materials/VideoDemo.
  5. Add the GvrVideoTexturePlayer script to the quad, located under GoogleVR/Scripts/Video.
  6. Set the properties in GvrVideoTextureplayer as follows:
    1. Video Type: Dash
    2. Buffer size: 4
    3. Video URL: https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_hd.mpd
    4. Video Content ID: https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_hd.mpd
    5. Video Provider ID: (leave blank)
  7. Add the VideoControls prefab, located under GoogleVR/Demos/Prefabs/VideoDemo.
    1. Set the Position to be (0,0,3).
  8. Attach the Video Player to the Video Controls.
    1. Under Video Player Reference Script, set Player to the video player object.
  9. At this point, your scene should have all the components as shown in the screenshot below.

    Save the scene and open File > Build Settings.

  10. Add the current scene to the scene list and make sure it's the first scene enabled.

  11. Press Build & Run to run the example.

Spherical Video

This example shows how to create a 360° video playback using DASH with a video hosted on Google Cloud Storage. To do this, we create a large sphere with the camera at the center and render the video on the inside of the sphere.

  1. Run all the steps in Setting up your scene.
  2. Configure the main camera.
    1. Set the Position to (0, 1, 0).
    2. Set Target Eye to both.
  3. Add the video player object.
    1. Create a Sphere object (Game Object > 3D Object > Sphere).
    2. Set the Position to (0,0,0).
    3. Set the Scale to (12,12,12).
  4. Add the video material to the video player object. This is what's shown until the video loads.
    1. In the Mesh Renderer component, expand Materials and set element 0 to be StereoPanoSphereMaterial, located under GoogleVR/Demos/Materials/VideoDemo.
  5. Add the GvrVideoTexturePlayer script to the sphere, located under GoogleVR/Scripts/Video
  6. Set the properties in the GvrVideoTextureplayer script as follows:
    1. Video Type: Dash
    2. Buffer size: 4
    3. Video URL: https://storage.googleapis.com/daydream-deveng.appspot.com/japan360/dash/japan_day06_eagle2_shot0005-2880px_40000kbps.mpd
    4. Video Content ID: (leave blank)
    5. Video Provider ID: (leave blank)
  7. Add the VideoControls prefab, located under GoogleVR/Demos/Prefabs/VideoDemo
    1. Set the Position to be (0,0,3).
  8. Attach the Video Player to the Video Controls.
    1. Under Video Player Reference Script, set Player to the video player object.
  9. Save the scene and open File > Build Settings.
    1. Add the current scene to the scene list and make sure it's the only scene enabled.
  10. Press Build & Run to run the example.

Dealing with large video assets

Locally storing videos using Asset Manager is a viable option when your APK file is under 100 MB, the maximum allowed file size for apps on the Google Play Store, but it is not uncommon to have video assets exceeding this limit. To work around this limit, the resources can be stored in an OBB file as follows:

  1. Place your video asset in Assets/StreamingAssets. Files in this folder will be copied unchanged to the target machine, where it then will be available from a specific folder. For more information, see Unity's documentation on Special Folders.

  2. Change the Video Texture Player properties to:

    1. Video Type: Other
    2. Video URL: jar:file://${Application.dataPath}!/assets/vid_bigbuckbunny.mp4
    3. Video Content ID: (leave blank)
    4. Video Provider ID: (leave blank)
  3. Open Player Settings. Under Publishing Settings check the Split Application Binary checkbox. This will create the OBB file.

  4. When deploying the application locally, the OBB file is copied to the correct location automatically. See this page on handling OBB files via the Play Store with Unity.

Switching video streams

To switch the video playing without destroying and creating a new TexturePlayer component:

  1. Set the video properties to the new stream on the GvrVideoTexturePlayer script, specifically, the VideoType, VideoURL, VideoContentID and VideoProviderID.
  2. Call TexturePlayer.CleanupVideo().
  3. Call TexturePlayer.ReinitializeVideo(). This will create a new instance of ExoPlayer.

Callbacks

OnVideoEvent

Because initializing the player and loading the video stream are asynchronous operations, it can be useful to have a callback when the video is ready. This is an alternative to polling the VideoReady property in the Update method. You can register a callback to be called when the video is ready by invoking GvrVideoTexturePlayer.OnVideoEventCallBack().

For example:

Getcomponent<TexturePlayer>().SetOnVideoEventCallback(eventId) => {
    Debug.Log("Video is ready!")
    UpdateStatusText();
);

The available eventIds are:

  • VideoReady
  • VideoStartPlayback
  • VideoFormatChanged
  • VideoSurfaceSet
  • VideoSizeChanged

OnException

When something goes wrong with the video playback, the player throws an exception. A callback can be registered to be invoked when exceptions occur by calling GvrVideoTexturePlayer.SetOnExceptionCallback(). For example:

GetComponent<TexturePlayer>().SetOnExceptionCallback(
   (type, message) => {
        Debug.LogError("Exception of type: " + type + ": " + message);
   }
);