Search Unity

Bug Addressable VideoClip on Android 9 or lower Not Working (Remote and Local)

Discussion in 'Addressables' started by Ruhan-_-, Sep 17, 2022.

  1. Ruhan-_-

    Ruhan-_-

    Joined:
    Sep 14, 2016
    Posts:
    20
    I tried Addressable Video Playback on Android using following versions:
    • Unity 2021.3.9 + Addressables 1.19.19
    • Unity 2022.1.16 + Addressables 1.20.5 (This project folder is zipped and attached to this post)
    Steps:
    1. Use Unity Recorder to record a simple scene with a cube in 1080p as both "H.264 MP4" and "VP8 WebM".
    2.png

    2. Use the default settings on Addressable Group and use Local cache.
    Addressable settings.png

    3. Wrote some code to run it:
    code.png

    Code:
    Code (CSharp):
    1. using TMPro;
    2. using UnityEngine;
    3. using UnityEngine.AddressableAssets;
    4. using UnityEngine.ResourceManagement.AsyncOperations;
    5. using UnityEngine.Video;
    6.  
    7. public class AddressableVideoTest : MonoBehaviour
    8. {
    9.     public AssetReference AssetReference;
    10.     public VideoPlayer VideoPlayer;
    11.     public TextMeshProUGUI ReportText;
    12.     private AsyncOperationHandle<VideoClip> op;
    13.    
    14.     private void Awake()
    15.     {
    16.         op = AssetReference.LoadAssetAsync<VideoClip>();
    17.         op.Completed += Completed;
    18.     }
    19.  
    20.     private void Completed( AsyncOperationHandle<VideoClip> result )
    21.     {
    22.         op.Completed -= Completed;
    23.         ReportText.text = op.Result.name + $"[API:{GetAndroidAPILevel()}] -- [Unity:{Application.unityVersion}]";
    24.         VideoPlayer.clip = op.Result;
    25.         VideoPlayer.Play();
    26.     }
    27.    
    28.     private static int GetAndroidAPILevel()
    29.     {
    30.     #if UNITY_EDITOR
    31.         return 29; // Assume Android 10 only for editor use
    32.     #endif
    33.        
    34.         string osInfo = SystemInfo.operatingSystem;
    35.         return !osInfo.Contains( "Android" ) ? 29 : new AndroidJavaClass("android.os.Build$VERSION").GetStatic<int>("SDK_INT");
    36.     }
    37. }
    38.  
    This works fine on Editor as well as any Android Device with API Level 29 or higher (aka Android OS 10.0 or higher). It also works fine on Windows and I am assuming it'll work on other platforms too.
    But when I try to run on any Android device lower than API Level 29 (Android OS 9.0 or lower) then this happens:
    Warning:
    "Autoconnected Player "Autoconnected Player" AndroidVideoMedia::OpenExtractor could not translate archive:/CAB-156a9f0d16bb33fc9bb9bb792bf6c6ba/CAB-156a9f0d16bb33fc9bb9bb792bf6c6ba.resource to local file. Make sure file exists, is on disk (not in memory) and not compressed."
    "Autoconnected Player "Autoconnected Player" AndroidVideoMedia: Error opening extractor: -10004"

    Keeping device connected, the console gets spammed with these 2 separate warnings repeatedly.
    This happens for both Unity versions mentioned above and MP4 + WebM formats.

    I stumbled upon this documentation that mentioned something at the end:
    https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/InitializeAsync.html

    NOTE
    Android applications built with Unity 202.1 or earlier or running on Android 9 or earlier can only play videos from uncompressed AssetBundles. You can use a CacheInitializationSettings object to disable recompression of the cache by disabling the Compress Bundles option.

    I think the "Unity 202.1" is a typo and it maybe meant 2021 or earlier. But I have tried this on 2021 and 2022 on their respective most stable current releases.

    On Addressable "Default Local Group" where I store the videos, I set it to "Uncompressed" for "Asset Bundle Compression". I also created CacheInitializationSettings.asset as mentioned on doc and assigned it to, making sure to uncheck "Compress Bundles".

    Absolutely nothing works.
    Our mobile game has come to heavily rely on video playback because we use it everywhere for background environments. It allows us to not worry about Scene Optimization and go nuts with effect usage. We are able to playback just fine from Resources folder. But we need to remotely download the videos to Android otherwise APK size will keep getting bigger, hence switch to Addressables. If anyone from the Addressable Unity Team can kindly help us, it would be highly appreciated! We MUST be able to play videos on Android API 28 or lower from Addressable download.

    One workaround we have found on a forum is to store the videos with ".bytes" file extension on Addressable group instead of the video format. Then after downloading the .bytes file, the following code converts to mp4 so it can be played like a URL on VideoPlayer component:

    Code (CSharp):
    1. Url = Path.Combine(Application.persistentDataPath, videoClipName + ".mp4");
    2. var textAsset = operationHandle.Result;
    3. File.WriteAllBytes( Url, textAsset.bytes);
    4. Addressables.Release( operationHandle );
    5. videoPlayer.url = Url;
    But this hack is very dirty as the file becomes exposed in storage directory for Application.persistentDataPath. Anyone can replace/change it as long as filename remains same. Not to mention we have to store every video twice, once as addressable download cache .bytes asset file and once as mp4 in storage. We can erase the addressable cache of course but this is too much overhead to keep track and maintain updates. It also makes the editor workflow a nuisance where the video files cannot even be viewed unless we keep another copy there too with correct extension.

    PLEASE HELP!!!
     

    Attached Files:

  2. Ruhan-_-

    Ruhan-_-

    Joined:
    Sep 14, 2016
    Posts:
    20
    I also went through this post, didn't help:
    https://forum.unity.com/threads/android-video-playback-failing-error-opening-extractor.803832/

    This maybe a core asset bundle related issue and it is reported as fixed:
    https://issuetracker.unity3d.com/issues/android-video-player-unable-to-play-video-from-asset-bundles

    But clearly addressables is not working correctly for android video download for OS 9 or earlier.

    Tried everything from here as well:
    https://forum.unity.com/threads/addressable-videos-not-working-on-android.588832/

    Our game is also played a lot on Bluestacks and even the latest version has API level below 29.

    Found the .bytes solution here but this is not a good workaround for such a bug:
    https://forum.unity.com/threads/load-videoclip-in-assetbundle-on-android.466850/page-2

    There is a solution to asset bundles but not addressables:
    https://forum.unity.com/threads/vid...g-videos-from-assetbundles-on-android.513983/
     
    Last edited: Sep 17, 2022
  3. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Your issue is a long known incompatibility with video's in assetbundles. It hasn't and won't/can't be 'fixed' for android 9 and lower. The only way of working around this is to either load assetbundles from persistentata and uncompressed (as you mentioned), or to download video's as separate files and load them from their respective paths.

    If you really are that worried about people replacing the content in an assetbundle i guess you can implement some hash check to verify its state before loading.
     
    Ruhan-_- likes this.
  4. Ruhan-_-

    Ruhan-_-

    Joined:
    Sep 14, 2016
    Posts:
    20
    @nilsdr Thank you for the response
    I was hoping there would be a way seeing as some of the forum posters resolved it somehow. I was hoping to be able to manage versions/downloads via addressable catalog but I guess .bytes is the only solution to get around it + keep using addressables