Search Unity

Need help with VideoPlayer

Discussion in 'Web' started by TOES2, May 25, 2017.

  1. TOES2

    TOES2

    Joined:
    May 20, 2013
    Posts:
    135
    I know WebGL is not officially supported on mobile devices, however I need to play videos using a mobile browser, and I cant make it work. Not even on a high end tablet.

    I have a very basic program just showing a plane with a VideoPlayer component on it. It is streaming a video from an URL, and everything works fine when using a desktop browser, so I know everything is set up properly on the server side and in the script.

    However, if on a mobile, the video prepareCompleted event is never fired, And I do not see any video playing.

    The video is a standard mp4 video, and I have tried many different versions of it. Such as 1080p, 720p and even a super memory and texture friendly 256x256. Still no go. Weirdly, in Chrome on Android the first frame of the video shows, but then it stops.

    I have tried both the latest Unity 5.6.1f1 as well as beta 2017.1.0b6

    I am completely stuck, any suggestions would be appreciated.

    This is my code:

    Code (CSharp):
    1.    
    2.     public string filename;
    3.     private VideoPlayer videoPlayer;
    4.     private string message = " ";
    5.  
    6.     void Start () {
    7.         gameObject.AddComponent<VideoPlayer>();
    8.         videoPlayer = GetComponent<VideoPlayer>();
    9.  
    10.         //Events
    11.         videoPlayer.errorReceived += (source, message) => { message+= "{error:"+message+"} "; };
    12.         videoPlayer.prepareCompleted += (source) => { message += "{video is prepared} "; videoPlayer.Play(); };
    13.         videoPlayer.started += (source) => { message += "{video has started} "; };
    14.  
    15.         videoPlayer.source = VideoSource.Url;
    16.         videoPlayer.url = Application.streamingAssetsPath+"/"+filename;
    17.  
    18.         message += videoPlayer.url;
    19.  
    20.         videoPlayer.isLooping = true;
    21.         videoPlayer.Prepare();
    22.         videoPlayer.Play();  //Also tried to not play here, but only in prepare event
    23.     }
    24.    
    25.     void Update () {
    26.     }
    27.  
    28.     void OnGUI()
    29.     {
    30.         string fps = "FPS: "+(int)(1f/Time.smoothDeltaTime)+" "+message;
    31.  
    32.         if (videoPlayer.isPrepared)
    33.             GUI.Label(new Rect(0, 0, Screen.width, 40), fps+"Video info: " + videoPlayer.texture.width + "x" + videoPlayer.texture.height+", frame: "+(int)(videoPlayer.time*videoPlayer.frameRate));
    34.         else
    35.             GUI.Label(new Rect(0, 0, Screen.width, 40), fps+"Video not prepared");
    36.     }
    37.  
    38.  
     
  2. ttw1993

    ttw1993

    Joined:
    Jul 19, 2017
    Posts:
    11
    try this code

    public IEnumerator Play()
    {
    vp.Prepare();
    while (!vp.isPrepared)
    {
    print("Prepareing: ");
    yield return null;
    }
    vp.Play();


    and call StartCoroutine(Play());
     
  3. Acromatic

    Acromatic

    Joined:
    Feb 2, 2021
    Posts:
    3
    This is a bit old, I'm working with the newest LTS... my method uses no coroutines. Instead I have a context window with elements that make up a playlist (in 3D UI). using those elements I make an enumerated list of strings. using the list count and index (and not the strings which are file paths) I determine if I've reached the end, using the loopEndReached callback of the current video player I attach PlayNextInList function which contains all of this. Example:

    Code (CSharp):
    1.            public void PlayNextInList(UnityEngine.Video.VideoPlayer videoPlayer)
    2.             {
    3.                 foreach (string item in listItems)
    4.                 {
    5.                     Debug.Log(listItems.IndexOf(item));
    6.                         Debug.Log(listItems.Count);
    7.  
    8.                     if (listItems.IndexOf(item) <= listItems.Count-1)
    9.                     {
    10.                         if (item.TrimStart(("./Assets/YoutubeCache/VideoCache/").ToCharArray()) == videoPlayer.url)
    11.                         {
    12.                                 //videoPlayer.url = item.ToString();
    13.                                 videoPlayer.url = listItems[+1];
    14.                                 //VideoPlayer.Prepare();
    15.                                 videoPlayer.Play();
    16.  
    17.                                 // Unity reports 0 length, these are files on the hard drive, weird
    18.                                 Debug.Log(item.TrimStart(("./Assets/YoutubeCache/VideoCache/").ToCharArray()) + " playing in playlist. Video Length: " + videoPlayer.length);
    19.                                 Debug.Log("Playing next song in playlist");
    20.                         }
    21.                     }
    22.                     else
    23.                     {
    24.                         videoPlayer.Stop();
    25.                         // End of playlist
    26.                         Debug.Log("End of playlist " + "Overflow" );
    27.                     }
    28.                 }
    29.             }
    It's the else Stop() that stops when the playlist is finished. Pretty clean I think for playlist functionality, I sort of stumbled upon... I like minimalist code that uses no support libs :)

    One major advantage of the LoopEndReached callback is that if the videoplayer object dies than it just cancels the functionality with it, this is also how the video player demo works but instead they add a multiplier to it, mine is just a function that it runs later, probably with an internal coroutine, which means maybe you're doubling coroutines.
     
    Last edited: Apr 8, 2021
  4. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    546