0
votes

I am trying to download a video(Bunny Video for testing) from a url and then play it using a video player component.

The issue I have here is that if I pass a pre downloaded clip or url to the video player in editor mode it plays video without any issue but when I try to add the VideoPlayer component dynamically to my gameobject and assign video clip to the video player, it never plays the video. Clip option always shows null in VideoPlayer component during play mode. Also adding url also doesn't work when done via script.

Here is my script which downloads the video and assign it to the videoplayer.

public class DownloadScript : MonoBehaviour
{



    private WWW Url;

    private VideoPlayer Player;
    public VideoClip clip;

    public float test;
    // Use this for initialization
    void Start ()
    {
        this.gameObject.AddComponent<VideoPlayer>();
        Player = this.gameObject.GetComponent<VideoPlayer>();
        _Download();
        /*Player.source=VideoSource.VideoClip;
        Player.clip = clip;
        Player.Prepare();*/


        //  Player.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";


    }

    // Update is called once per frame
    void Update () {

        if (!Player.isPlaying && Player.isPrepared)
        {
            Player.Play();

        }
    }
    private IEnumerator WaitForDownload(string sURL)
    {
        Url = new WWW(sURL);
        //WWW www = new WWW(sURL);
        Debug.Log(Url.bytesDownloaded);
        yield return Url;
        if (Url.isDone)
        {
            Debug.Log("Player ready");
            Invoke("PlayVideo",20f);
        }   
        else
        {
            Debug.Log(Url.bytesDownloaded);
        }

        yield return Url;

    }
    private void _Download()
    {
        try
        {  
            StartCoroutine(WaitForDownload("http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"));
        //  return Url.bytes;  
        }
        catch(Exception e)
        {
            Debug.Log(e.ToString());
        }


    }

    public void PlayVideo()
    {
        Debug.Log("url download complete");
        File.WriteAllBytes(Application.dataPath + "/Resources"+"/bunny.mp4", Url.bytes);


        clip =(VideoClip) Resources.Load("bunny.mp4");
        Player.source=VideoSource.VideoClip;
        Player.clip = clip;
        test = 5.0f;
        //  Player.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
        if (Player.isPrepared)
        {
            Player.Play();
        }
    }
}

Here is the screenshot of the inspector panel at runtime.

Inspector

I added a test variable in my script to verify if anything is getting updated at runtime or not. So the value of test variable is updated in the inspector panel but the video clip value doesn't update and that's why my video doesn't get played.

Any solution for this ?

1

1 Answers

3
votes

So I had the same problem. Just got it resolved.

CODE :

private void Start()
{
    StartCoroutine(this.loadVideoFromThisURL(videoUrl));
}

[SerializeField]
internal UnityEngine.Video.VideoPlayer myVideoPlayer;
string videoUrl ="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
private IEnumerator loadVideoFromThisURL(string _url)
{
    UnityWebRequest _videoRequest = UnityWebRequest.Get (_url);

    yield return _videoRequest.SendWebRequest();

    if (_videoRequest.isDone == false || _videoRequest.error != null)
    {   Debug.Log ("Request = " + _videoRequest.error );}

    Debug.Log ("Video Done - " + _videoRequest.isDone);

    byte[] _videoBytes = _videoRequest.downloadHandler.data;

    string _pathToFile = Path.Combine (Application.persistentDataPath, "movie.mp4");
    File.WriteAllBytes (_pathToFile, _videoBytes);
    Debug.Log (_pathToFile);
    StartCoroutine(this.playThisURLInVideo (_pathToFile));
    yield return null;
}


private IEnumerator playThisURLInVideo(string _url)
{
    myVideoPlayer.source = UnityEngine.Video.VideoSource.Url;
    myVideoPlayer.url = _url;
    myVideoPlayer.Prepare ();

    while (myVideoPlayer.isPrepared == false)
    {   yield return null;}

    Debug.Log ("Video should play");
    myVideoPlayer.Play ();
}

SOLUTION :

From your code, I see that you save your bytes to the Resources folder. That is not needed. Consequently you don't have to load it using Resources.Load.

Just pass in absolute filepath. I have tested in iOS and Mac OS. It works.