Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Unity 360 Video Player Library - Implementation / Solution

Discussion in 'AR/VR (XR) Discussion' started by voyagelms, Dec 5, 2018.

  1. voyagelms


    Jul 12, 2017
    Hello everyone!

    I wanted to share with everyone a simple wrapper library I wrote that makes managing and playing 360 video content super easy and painless, especially if those video assets are hosted externally.

    Please note that this library has not been unit tested and therefore not production compliant.
    With that said, I'd greatly appreciate any PRs or feedback on improving this library.

    You may find a very *light* overview of the library's features here at this Medium article, but I strongly suggest reading through the and the source code at the Github repository here for a holistic understanding of the library.

    I've intentionally made the library as simplistic as possible, and I'd be happy to answer any questions should anyone have them.

    ( Also, if anyone has any feedback / revisions for the Medium article, I'd greatly appreciate it!! )

    The library has been tested to work against the following Unity version. The library primarily targets the mobile platform, and has been tested against the Android library. There are no guarantees on how this library will work on other platforms.
    Unity : 2017.4.16f1

    Last but not least, if anyone can provide any feedback on how to turn this library into a completely production compliant library, I'd greatly appreciate it!!
    My experience and knowledge of Unity in a professional capacity is quite limited, so I'd be incredibly grateful if any individuals are willing to share their wisdoms. :)

    Problem | Inspiration
    When trying to play 360 video content hosted externally using Unity's Video Player component, I could never achieve consistent results using URLs as the component source.

    Rather than committing a ton of time debugging a black boxed component with no source code access, I decided to implement a wrapper library around what is known to work consistently, which is playing local 360 video content.

    adrenak's UniVRMedia provided excellent inspiration on how this could be done.

    General Features

    The main idea was to shift as much responsibility from the Video Player component and encapsulate those functionalities in dedicated classes.
    • ( AssetDownloader ) - Downloading video assets are asynchronously handled via UnityFx.Async
    • ( PlayerConfigurator ) - Unlit textures, inverting normal vectors, and flipping mirrored videos are handled in a dedicated PlayerConfigurator class.
    • ( VideoCollectionManager ) - Collections of videos are managed within the VideoCollectionManager, where upon a lowMemory alert ( provided by Application.lowMemory callback ), all downloaded video assets are purged.
    • ( MasterPlayerController ) - Public API access is provided by the MasterPlayerController class.


    The library has been exported as a UnityPackage and may be downloaded here.
    The VideoSphere prefab has been packaged and configured to play 360 video content.
    Refer to the in the repository for additional instructions.

    Best Practices

    Although asynchronous downloads for video assets are supported, progress updates for ongoing downloads has not been implemented. However, this is completely feasible given how robust and feature rich the UnityFx.Async library is. ( Tangent : Totally recommend giving this asset a 5 star rating on the Unity Asset store. What a great library!! )

    As a result, depending on the size of the video asset, there are two scenarios.
    • Given that a video asset is very large ( > 100 MB or so ) and network speeds are at broadband levels, each URL should have a dedicated VideoSphere prefab, such that there can be multiple asynchronous downloads executing in parallel.

      The main idea is that each VideoSphere creates its own thread for downloading video. Although this is very resource intensive, I feel it's a better compromise than dealing with weird race cases in the following scenario.
    • A single VideoSphere handling a collection of video URLs. This is where things can get very muddy. Although downloads may occur asynchronously, unexpected behavior may occur when calling either "loadVideo" and "playVideo" when either functions have already been called.

      As a result, the best case scenario for using a single VideoSphere for a collection of VideoURLs is to avoid using loadVideo and *only* using playVideo. At least until the progress indicator feature has been implemented. :)
    Note: 8K video playback is not supported, but then again I haven't tried implementing it. ;)

    Anyways, I hope everyone can benefit from this!!


    P.S. If this library has helped you in any way, please consider starring the GitHub repository or supporting me on Patreon!! Either way, I hope this library saves you a few headaches!! :D
    Last edited: Dec 5, 2018
  2. voyagelms


    Jul 12, 2017


    With this release, I address three general features or implementations.
    • VideoPlayer controls: Through the MasterPlayerController class, functions such as stopVideo, resumeVideo, pauseVideo, and playVideo have been implemented and/or reworked due to added functionality.
    • Progress tracking: Currently downloaded assets now post numeric progress changes [0, 100] of type in through the handler handleDownloadProgress within the MasterPlayerController class. Refer to Readme for more details.
    • Download queue: Assets to be downloaded are now placed in a queue, which are processed on demand. Note that populating the VideoCollectionManager with more than one asset does not mean that they will be downloaded immediately. It is the developer's responsibility to explicitly enqueue the video using the functions provided in the MasterPlayerController class.
    • Supporting functions: File check functions, such as isAssetDownloaded and isAssetInDownloadQueue have been added to determine a video's download state.
    If there is any feedback, questions, or suggestions, please open them in the Issue tracker. :)