Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Video Player doesnt work properly in VR

Discussion in 'VR' started by Munvik, Jul 26, 2023.

  1. Munvik

    Munvik

    Joined:
    May 5, 2019
    Posts:
    5
    Hello. We have an issue with Video Player in Oculus Quest 2. We have 3 video players on scene or sometimes more.. It seems like those video players bites with each other.



    How its done:
    We download .mp4 files on storage on device. Then if its downloaded we play the video player.
    Here is the code
    Code (CSharp):
    1. private void OnVideoDownload(DownloadHandler downloadHandler, string videoName)
    2.         {        
    3.             string fileExtension = GetVideoFileNameExtension(videoName);
    4.             videoName = videoName.Replace("." + fileExtension, string.Empty);
    5.  
    6.             string videoPath = Application.persistentDataPath + "/" + videoName + "." + fileExtension;
    7.  
    8.             if (!File.Exists(videoPath))
    9.             {
    10.                 File.WriteAllBytes(videoPath, downloadHandler.data);
    11.             }
    12.  
    13.             player.url = videoPath;
    14.             screenMesh.gameObject.SetActive(true);
    15.             player.Play();
    16.  
    17.             player.errorReceived -= ErrorAppeared;
    18.         }
    It looks good. Here everything is fine in Editor.
    We even copy the materials and render texture in videoplayers. Everything its fine. On WebGL, in Editor but not in VR on Android.

    What are we doing wrong? Where can we search the solution? Is it a bug?
     
  2. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    450
    By copying the materials and render textures you mean every video player uses a different render texture? If not, make sure they do. It looks like each video player tries to render into the same render texture at the same time.

    Perhaps you have some platform specific code somewhere, which changes the behaviour to be incorrect in VR. For example changing the behaviour in such a way that videos are rendered into the same RT.
    Add some debug logs to make sure that at runtime the video players use different render textures.

    Also, what is the Render Mode of the Video Player? Render texture or material override?
     
  3. Munvik

    Munvik

    Joined:
    May 5, 2019
    Posts:
    5
    Yea, we are sure we have different render textures and materials by checking its id.

    Code (CSharp):
    1. var materialCopy = Instantiate(screenMesh.material);
    2.             var renderTextureCopy = Instantiate(player.targetTexture);
    3.  
    4.             player.targetTexture = renderTextureCopy;
    5.             materialCopy.SetTexture("_BaseMap", renderTextureCopy);
    6.             screenMesh.material = materialCopy;
    We are doing it per player.
    The Render Mode is set to Render Texture

    According to your words that we are doing something different on Android.. Yes we are doing different.
    There is a code:
    Code (CSharp):
    1. #if UNITY_ANDROID
    2.             string videoFilename = GetVideoFileNameFromURL(fixedUrl);
    3.             UnityWebRequest www = UnityWebRequest.Get(fixedUrl);
    4.             Rest.Request(www, (handler) => OnVideoDownload(handler, videoFilename), (fail) => Debug.Log("Rest failed, message: " + fail));
    5.             return;
    6. #else
    7.             player.url = fixedUrl;
    8.             player.Play();
    9.             screenMesh.gameObject.SetActive(true);
    10. #endif
    The OnVideoDownload() body is up but here is again:
    Code (CSharp):
    1. private void OnVideoDownload(DownloadHandler downloadHandler, string videoName)
    2.         {      
    3.             string fileExtension = GetVideoFileNameExtension(videoName);
    4.             videoName = videoName.Replace("." + fileExtension, string.Empty);
    5.             string videoPath = Application.persistentDataPath + "/" + videoName + "." + fileExtension;
    6.             if (!File.Exists(videoPath))
    7.             {
    8.                 File.WriteAllBytes(videoPath, downloadHandler.data);
    9.             }
    10.             player.url = videoPath;
    11.             screenMesh.gameObject.SetActive(true);
    12.             player.Play();
    13.             player.errorReceived -= ErrorAppeared;
    14.         }
    We are downloading a file because that was worse when we used the streaming on Android because the screens were black because we had an error "No path to file", like Android forced to use the path to its storage.

    That solution we have now works in Editor when Im on Android platform.
     
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,317
    This line:
    Does not look right.

    Because RenderTexture is a wrapper object that stores a handle to a GPU resource.

    Is this even supported officially? What happens if you use constructor normally?
    https://docs.unity3d.com/ScriptReference/RenderTexture-ctor.html
     
  5. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    450
    While I realize that this probably won't make a difference then for the sake of trying, one of the differences you have in this platform specific code is that in the case of non-android platform you do player.Play() before you set the screenmesh gameobject active. On Android this order is reversed. Perhaps there is some difference in this order that causes your issue.