Search Unity

Video Load VideoClip in assetbundle on Android

Discussion in 'Audio & Video' started by VianneyThurotte, Apr 18, 2017.

  1. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    The above method had been detailed a couple of times before and works. You can download the bundles to persistent data then load from there. You'd have to write your own caching layer
     
  2. hertatra

    hertatra

    Joined:
    Jul 12, 2017
    Posts:
    1
    You said "Second, use AssetBundle.LoadFromFile() to load your AssetBundle instead of using WWW." but what if my asset bundle is in the server. How can i download from server using AssetBundle.LoadFromFile()?
     
  3. Viewzoom

    Viewzoom

    Joined:
    Jan 16, 2016
    Posts:
    7
    You should download and save the AssetBundle to the persistentDataPath before you Load it.
     
  4. ManuelLoaiza

    ManuelLoaiza

    Joined:
    Jan 3, 2019
    Posts:
    1
    Hi Everyone, in my case I put my complete scene into an assetbundle , in this scene I define a videoclip which is set using a .webm file. This videoclip is played using a videoplayer gameobject. But , how you known in Android I can't play this file from my assetbundle after download and cached it. I test the suggested solution , that is to download this video file from the webserver and copy them to my persistentDataPath and after copy instantiate my videoplayer from this path and read from that my .webm file. This soloution worked ok !!. My question is, inside my assetbundle is zipped my webm file, how I can save or extract the video file inside assetbundle and save it into the persistentDataPath, I load the scene and inside the scene I have a videoclip object that have the referenced to webm file, but how I copy this video file and save it inside my persistentDataPath, anyone have try to do that ???, thanks for your help.
     
    IvanIvanovP3 likes this.
  5. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374

    You can not extract the video from an assetbundle to persistent data. You can either download the assetbundle itself to a file instead of cache and load it from there (uncompressed!), or download the video file separately from the bundle and store it in persistent data.
     
  6. multimediamarkers

    multimediamarkers

    Joined:
    Feb 17, 2016
    Posts:
    49
    Any news from @Unity for solving the bug on video's in Assetbundles for Android?
     
  7. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    186
    Please try to use "UnCompressed" AssetBundles on android for videos.
     
  8. lloydhooson

    lloydhooson

    Joined:
    Apr 7, 2008
    Posts:
    77
    Hi, is this issue going to be resolved from asset-bundles that are cached? I'm currently using the "UnityWebRequestAssetBundle.GetAssetBundle" and this for video content fine for iOS, Windows, OSX, but not at all for android. Do I have to change the whole asset-bundle system for video to work on android?

    Thanks.
     
  9. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Unity doesn't consider this a bug and therefor it won't be "fixed", word from Unity team:

    this is a known limitation. It should have been documented in the first place: I'm adding a line about this in the VideoPlayer API doc so future users don't have to discover this by experimentation. The limitation is imposed by the subset of the Android media API that we are restricting ourselves to, which lets us uniformly support Android versions 16 and up for movie playback.

    Asset bundles are normally accessed by Unity's internals via a filesystem abstraction layer that is specific to Unity, which we call the VFS (Virtual File System). This abstraction lets Unity internal code read "files" in this VFS by abstracting out whether the file content is compressed/uncompressed, in memory or on disk. However, prior to API level 23/6.0 in Java (and 28/9.0 - in C++), the Android media API doesn't allow intercepting i/o calls to redirect them to an arbitrary implementation; in Unity's case, this would be the VFS.
     
    ShantiB95, IvanIvanovP3 and rytalfo like this.
  10. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
  11. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    Is there any progress about this issue?
     
  12. AlekseiBegali

    AlekseiBegali

    Joined:
    Oct 10, 2017
    Posts:
    4
    Hi, had same issue.
    Main problem is between Android native video player and Unity. Android just can't play video file from COMPRESSED Asset Bundles.
    But, when you loading Asset Bundles, despite compressed they are or not, they will be stored in Cache - which can be Compressed or Uncompressed too (UnityEngine.Caching.compressionEnabled). So, if you are downloading compressed Asset Bundle when cache compression is disabled, Android video player WILL play video from that Bundle, because Asset Bundle will be stored uncompressed.
    It's not a solution, but for me I wrote Asset Bundle downloading manager, which enables or disables Cache compression depending on Asset Bundle (if it contains video or not). It's better than leaving all Asset Bundles uncompressed. It saves traffic and device storage.
    Tested on Unity 2018.3.5f1
     
    SooryaCS, gamevagrant and nilsdr like this.
  13. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Can this setting be toggled per assetbundle?
     
  14. UweR7

    UweR7

    Joined:
    Jul 27, 2017
    Posts:
    20
    Thanks for your tip/advise! Sounds good. But in the meantime I wrote my own workaround:
    Aloso videos are separated during asset bundles build.
    Both kinds (videos and asset bundles) are than copied to a server.

    At run time are the asset bundles and the related videos (and other separated files) downloaded, stored on the device and used.
    I wrote also my own caching class to handle it as I like.
     
  15. Shane-Pangea

    Shane-Pangea

    Joined:
    Dec 12, 2012
    Posts:
    38
    @UweR7 that sounds great! Can you share your solution with the thread?
     
  16. Shane-Pangea

    Shane-Pangea

    Joined:
    Dec 12, 2012
    Posts:
    38
    I found this video that explains loading videos from Asset Bundles on Android. Looks like the key is setting the cache compression to false as @AlekseiBegali mentioned. I haven't checked it out for myself yet, but it looks promising!

     
    SheZii00 likes this.
  17. gamevagrant

    gamevagrant

    Joined:
    Aug 7, 2019
    Posts:
    1
    Code (CSharp):
    1.  
    2. private void Awake()
    3.     {
    4.         Caching.ClearCache();
    5.         Caching.compressionEnabled = false;
    6.     }
    7. private IEnumerator LoadAssetBundle(string path, string name)
    8. {
    9.         string assetbundleName = PathUtils.GetAssetBundleNameWithPath(path, FilePathTools.root);
    10.         AssetBundle manifestBundle = AssetBundle.LoadFromFile(FilePathTools.manifestPath);
    11.         AssetBundleManifest manifest = manifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    12.         Hash128 hash = manifest.GetAssetBundleHash(assetbundleName);
    13.  
    14.         string cachePath = FilePathTools.tmpPath;
    15.  
    16.         if (!Directory.Exists(cachePath))
    17.             Directory.CreateDirectory(cachePath);
    18.         Cache newCache = Caching.AddCache(cachePath);
    19.  
    20.         if (newCache.valid)
    21.             Caching.currentCacheForWriting = newCache;
    22.         path = "file://" + path;
    23.  
    24.         UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(path, hash);
    25.         yield return request.SendWebRequest();
    26.         if (!string.IsNullOrEmpty(request.error))
    27.         {
    28.             Debug.LogError(request.error);
    29.             yield break;
    30.         }
    31.         AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
    32.         var clip = bundle.LoadAsset<VideoClip>(name);
    33.         PlayVideoClip(clip);
    34.         yield return null;
    35.         bundle.Unload(false);
    36.     }
    @AlekseiBegali is right
     
  18. AlekseiBegali

    AlekseiBegali

    Joined:
    Oct 10, 2017
    Posts:
    4
    Unfortunately - not.
    Caching.compressionEnabled property affects only further downloads. It doesn't compress or decompress existing content in the cache. So before loading you need to check every bundle for compression allowance. For instance, you can use file with bundle names, use "VIDEO_" prefix for asset bundle name, etc.
    It has it's own disadvantages - you can't load compressed and uncompressed bundles simultaneously.
     
    Last edited: Sep 24, 2019
  19. AlekseiBegali

    AlekseiBegali

    Joined:
    Oct 10, 2017
    Posts:
    4
    It was our first approach. But, because of loaded data size limit for application and usage of auto cache cleaner it was better to find a solution for storing video in Asset Bundles.
     
  20. AlekseiBegali

    AlekseiBegali

    Joined:
    Oct 10, 2017
    Posts:
    4
    @Shane-Pangea , @gamevagrant Still be carefull, disabling cache compression at all may cause device memory shortage, especially on low-end devices. Uncompressed asset bundles can be 3-4 times bigger than compressed.
     
  21. Alex_Heizenrader

    Alex_Heizenrader

    Joined:
    May 16, 2019
    Posts:
    95
    Simply making the bundle uncompressed and loading from file worked for us, still it is ridiculous since I want as little size as possible for this bundles in mobile, I don't understand why they don't fix it as per their description for higher Android versions...
     
    Mashimaro7 and lloydhooson like this.
  22. SharrTZaw

    SharrTZaw

    Joined:
    Mar 30, 2019
    Posts:
    13
    Hello I use videoPlayer in 3D quads with url "https://" in my vuforia project. I didn't see any video play in my quad stay white. Here is my code.
    private VideoPlayer vdplayer;
    OnTrackingFound()
    var vdplayer = gameObject.GetComponentInChildren<VideoPlayer>(true);

    vdplayer.source = VideoSource.Url;
    vdplayer.renderMode = VideoRenderMode.MaterialOverride;
    vdplayer.targetMaterialRenderer = GetComponent<Renderer>();
    vdplayer.targetMaterialProperty = "_MainTex";
    vdplayer.Prepare();
    vdplayer.Play();

    all the AR components are appear but didn't play any video. I appreciate to any help. thanks.
     
    Murad-Khafizov likes this.
  23. moderebel

    moderebel

    Joined:
    Feb 20, 2018
    Posts:
    4
    This solution WORKS. The key to the solution is in using the DownloadHandlerFile for the WR. I've seen other "solutions" that use AssetBundle.LoadFromFile, but none of them worked - the DHF is the key.

    Thank you so much for posting this. It came as much relief after days of frustration.
     
    nilsdr likes this.
  24. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    As of Unity 2020.2 this has been fixed, but only for Android 9 and up
     
  25. canyon_gyh

    canyon_gyh

    Joined:
    Aug 15, 2018
    Posts:
    48
    i think that:
    put the videoclip
    1 Resources folder , use Resources.Load<VideoClip> or Resources.LoadAsync<VideoClip>
    2 streamingAssetsPath ,use url like videoplay.url = Application.streamingAssetsPath + "/xxx"
    3. web_url
    the url ,we can download it to persistentDataPath,
    then use url like videoplay.url = Application.persistentDataPath + "/xxx" ;
    may also using it to videoplay.url = web_url
     
  26. powereborn

    powereborn

    Joined:
    Dec 22, 2018
    Posts:
    5
    We are end of 2021 and there is no fix for this, What's happening ? I thought fixing such big issues would be a priority :)

    Edit:
    Searching in multiple threads, I just read https://forum.unity.com/threads/vid...g-videos-from-assetbundles-on-android.513983/. In concluson, there are 2 solutions here:
    - Either hosting on the web the video and playing in stream or downloading them then playing them
    - Or put video in dedicated directory, disable compression. This solution seems to work but might not be optimal nevertheless, you could have further issues due to compression being disabled.

    Edit again:
    After searching on more solutions, there is another way which is working.
    - Rename video blabla.mp4 to blabla.bytes
    - Download assetbundle, load video bytes as TextAsset
    - Save the bytes to persistent data disk as mp4 video
    - Load mp4 video with videoplayer.url and it works

    Alright here is a piece of code in case it can help:

    Code (CSharp):
    1.  private IEnumerator loadVideo(string pathvideo)
    2.     {
    3.         assetBundleRequest = DownloadingScreenManager.getInstance().getMapAssetBundle()["vide_bundlename"].LoadAssetAsync<TextAsset>(pathvideo);
    4.  
    5.         yield return assetBundleRequest;
    6.  
    7.         textAsset = (TextAsset)assetBundleRequest.asset;
    8.  
    9.         File.WriteAllBytes(Path.Combine(Application.persistentDataPath, pathvideo + ".mp4"), textAsset.bytes);
    10.  
    11.         string url = Application.persistentDataPath + "/" + pathvideo + ".mp4";
    12.  
    13.         videoPlayer.url = url;
    14.     }
    15.  
     
    Last edited: Nov 12, 2021
  27. ShantiB95

    ShantiB95

    Joined:
    Feb 8, 2017
    Posts:
    17
    OMFG!!!! @powereborn You have saved my head from exploding and also me losing my job! Thank you for this solution! Worked like a charm!

    Now next step for me, load >1GB video files as TextAssets! All thanks to Unity!
     
    Last edited: May 29, 2022
    Mashimaro7 likes this.
  28. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    727
    I had this same problem, i couldn't find anything after googling for hours. Seems like this would be a pretty easy fix for Unity to provide?? I don't really understand that text asset solution, i've opted for just uploading the videos to dropbox... Crazy that this thread was created 5 years ago and Unity still hasn't fixed it... My asset bundles were nothing more than a list of videos, and none of them worked...

    And no, turning off compression and spending hours reuploading them all did not fix it lol
     
    CloudyVR and ShantiB95 like this.
  29. The_Island

    The_Island

    Unity Technologies

    Joined:
    Jun 1, 2021
    Posts:
    502
    You can check the section for playing video files on Android. We support playback from uncompressed asset bundles on all devices. For Android Pie and above, Unity supports playback from compressed asset bundles.
    https://docs.unity3d.com/Manual/android-requirements-and-compatibility.html

    Maybe you have the same problem as him. It is possible the VideoClip class got stripped.
    https://forum.unity.com/threads/videoclip-in-assetbundle-on-ios.988364/
    https://github.com/google/play-unity-plugins/issues/117

    If can you share an error from ADB, code or anything I can try to help you? :)
     
    Last edited: Sep 21, 2022
    Mashimaro7 likes this.
  30. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Support on legacy devices is only for bundles loaded from filesystem, so not unitywebrequest caching mechanism.
     
  31. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    727
    Thanks for the reply, i didn't see it until today.

    My asset bundles were just lists video clips, I was downloading them, populating them in a dictionary, then unloading the bundle. I tried with both compressed and uncompressed bundles, and each time got the same error, "Video clip could not be read". But even if it worked uncompressed(which it doesn't) i wonder why it doesn't work compressed? Some of the video clips are very large, 200mb, and i can compress them down to 10-20mb.

    So, as per that forum post, it's a better idea to add the video clip class instead of a list in a script?
     
  32. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    the key is in how you load the bundles. can you post your code?
     
  33. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    727
    Oh geez, my code is gone now lol. Basically I was just writing it to disc with File.WriteAllBytes, and the loading it with AssetBundle.LoadFromFile, taking the video off and putting it in a list, then unloading the bundle.
     
  34. ShantiB95

    ShantiB95

    Joined:
    Feb 8, 2017
    Posts:
    17
    I am pretty sure I had tried this solution for the "VideoClip class got stripped" part (which is an absurd anomaly in itself as it was clearly referenced at multiple instances in the project) which did not work. But I see some newer lines in that solution which I may have to try someday.

    Also @Mashimaro7 I had to devise some new methods as the 'TextAsset' method was crashing the app due to memory usage cap. Specifically, I had used a zip file chunk loading solution. Unity seems to have a knack for making us devs go crazy over puny stuff. Also, I've not updated myself, but it seems this particular bug has been carried forward into Addressables too! Cheers!
     
    Last edited: Feb 12, 2023
  35. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    So what do you experience, do you get an error in the log?

    Unity strips classes that are not referenced anywhere when building. If your videoclips are not referenced anywhere (other than in assetbundles / assets loaded from assetbundles) it will strip the class. The link.xml allows you to explicitly include namespaces and classes, regardless of whether they're used.
     
  36. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    This is kind of silly to push onto us to fix.

    Could the video player not be smart enough to query android SDK version and extract the video to a file on disk and stream that instead? Why not hide this implementation detail from us.

    I added some logic to wait for the video to start playing before proceeding to the next screen, and unintentionally bricked all android 8 and bellow devices because of this issue.

    It's a trap waiting for every developer using addressables/asset bundles who missed the warning on the documentation. And every developer will have to write their own workaround.
     
    ShantiB95 likes this.
  37. ShantiB95

    ShantiB95

    Joined:
    Feb 8, 2017
    Posts:
    17
    Sometimes I regret getting into this path and think web/full-stack dev would have been so smooth for me with all the stable/ample support, just because of the amount of trauma Unity has given me :confused::rolleyes:
     
    Muckel and Prodigga like this.
  38. nikhildhamsania

    nikhildhamsania

    Joined:
    May 4, 2019
    Posts:
    2
    still it's not working in unity 2022.3.12f1.
     
    Dargon_huihui likes this.
  39. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,511
    There's the [Preserve] Attribute too https://docs.unity3d.com/ScriptReference/Scripting.PreserveAttribute.html