Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using new Unity VideoPlayer and VideoClip API to play video

Tags:

c#

unity3d

unity5

MovieTexture is finally deprecated after Unity 5.6.0b1 release and new API that plays video on both Desktop and Mobile devices is now released.

VideoPlayer and VideoClip can be used to play video and retrieve texture for each frame if needed.

I've managed to get the video working but coduldn't get the audio to play as-well from the Editor on Windows 10. Anyone know why audio is not playing?

//Raw Image to Show Video Images [Assign from the Editor] public RawImage image; //Video To Play [Assign from the Editor] public VideoClip videoToPlay;  private VideoPlayer videoPlayer; private VideoSource videoSource;  //Audio private AudioSource audioSource;  // Use this for initialization void Start() {     Application.runInBackground = true;     StartCoroutine(playVideo()); }  IEnumerator playVideo() {     //Add VideoPlayer to the GameObject     videoPlayer = gameObject.AddComponent<VideoPlayer>();      //Add AudioSource     audioSource = gameObject.AddComponent<AudioSource>();      //Disable Play on Awake for both Video and Audio     videoPlayer.playOnAwake = false;     audioSource.playOnAwake = false;      //We want to play from video clip not from url     videoPlayer.source = VideoSource.VideoClip;      //Set video To Play then prepare Audio to prevent Buffering     videoPlayer.clip = videoToPlay;     videoPlayer.Prepare();      //Wait until video is prepared     while (!videoPlayer.isPrepared)     {         Debug.Log("Preparing Video");         yield return null;     }      Debug.Log("Done Preparing Video");      //Set Audio Output to AudioSource     videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;      //Assign the Audio from Video to AudioSource to be played     videoPlayer.EnableAudioTrack(0, true);     videoPlayer.SetTargetAudioSource(0, audioSource);      //Assign the Texture from Video to RawImage to be displayed     image.texture = videoPlayer.texture;      //Play Video     videoPlayer.Play();      //Play Sound     audioSource.Play();      Debug.Log("Playing Video");     while (videoPlayer.isPlaying)     {         Debug.LogWarning("Video Time: " + Mathf.FloorToInt((float)videoPlayer.time));         yield return null;     }      Debug.Log("Done Playing Video"); } 
like image 993
Programmer Avatar asked Dec 14 '16 13:12

Programmer


People also ask

How do I play video in unity WebGL?

Unity WebGL doesn't support playing video directly from assets! You can either place your video under StreamingAssets path or external file server, then you can provide the video URL as the source. Even then you would need to take care of following: CORS in case of external file server.


2 Answers

Found the problem. Below is the FIXED code that plays Video and Audio:

//Raw Image to Show Video Images [Assign from the Editor] public RawImage image; //Video To Play [Assign from the Editor] public VideoClip videoToPlay;  private VideoPlayer videoPlayer; private VideoSource videoSource;  //Audio private AudioSource audioSource;  // Use this for initialization void Start() {     Application.runInBackground = true;     StartCoroutine(playVideo()); }  IEnumerator playVideo() {     //Add VideoPlayer to the GameObject     videoPlayer = gameObject.AddComponent<VideoPlayer>();      //Add AudioSource     audioSource = gameObject.AddComponent<AudioSource>();      //Disable Play on Awake for both Video and Audio     videoPlayer.playOnAwake = false;     audioSource.playOnAwake = false;      //We want to play from video clip not from url     videoPlayer.source = VideoSource.VideoClip;      //Set Audio Output to AudioSource     videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;      //Assign the Audio from Video to AudioSource to be played     videoPlayer.EnableAudioTrack(0, true);     videoPlayer.SetTargetAudioSource(0, audioSource);      //Set video To Play then prepare Audio to prevent Buffering     videoPlayer.clip = videoToPlay;     videoPlayer.Prepare();      //Wait until video is prepared     while (!videoPlayer.isPrepared)     {         Debug.Log("Preparing Video");         yield return null;     }      Debug.Log("Done Preparing Video");      //Assign the Texture from Video to RawImage to be displayed     image.texture = videoPlayer.texture;      //Play Video     videoPlayer.Play();      //Play Sound     audioSource.Play();      Debug.Log("Playing Video");     while (videoPlayer.isPlaying)     {         Debug.LogWarning("Video Time: " + Mathf.FloorToInt((float)videoPlayer.time));         yield return null;     }      Debug.Log("Done Playing Video"); } 

Why Audio was not playing:

//Set Audio Output to AudioSource videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;  //Assign the Audio from Video to AudioSource to be played videoPlayer.EnableAudioTrack(0, true); videoPlayer.SetTargetAudioSource(0, audioSource); 

must be called before videoPlayer.Prepare(); not after it. This is took hours of experiment to find this this was the problem I was having.


Stuck at "Preparing Video"?

Wait 5 seconds after videoPlayer.Prepare(); is called then exit the while loop.

Replace:

while (!videoPlayer.isPrepared) {     Debug.Log("Preparing Video");     yield return null; } 

with:

//Wait until video is prepared WaitForSeconds waitTime = new WaitForSeconds(5); while (!videoPlayer.isPrepared) {     Debug.Log("Preparing Video");     //Prepare/Wait for 5 sceonds only     yield return waitTime;     //Break out of the while loop after 5 seconds wait     break; } 

This should work but you may experience buffering when the video starts playing. While using this temporary fix, my suggestion is to file for bug with the title of "videoPlayer.isPrepared always true" because this is a bug.

Some people also fixed it by changing:

videoPlayer.playOnAwake = false;  audioSource.playOnAwake = false; 

to

videoPlayer.playOnAwake = true;  audioSource.playOnAwake = true; 

Play Video From URL:

Replace:

//We want to play from video clip not from url videoPlayer.source = VideoSource.VideoClip; 

with:

//We want to play from url videoPlayer.source = VideoSource.Url; videoPlayer.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"; 

then Remove:

public VideoClip videoToPlay; and videoPlayer.clip = videoToPlay; as these are not needed anymore.

Play Video From StreamingAssets folder:

string url = "file://" + Application.streamingAssetsPath + "/" + "VideoName.mp4";  if !UNITY_EDITOR && UNITY_ANDROID     url = Application.streamingAssetsPath + "/" + "VideoName.mp4"; #endif  //We want to play from url videoPlayer.source = VideoSource.Url; videoPlayer.url = url; 

All supported video formats:

  • ogv
  • vp8
  • webm
  • mov
  • dv
  • mp4
  • m4v
  • mpg
  • mpeg

Extra supported video formats on Windows:

  • avi
  • asf
  • wmf

Some of these formats don't work on some platforms. See this post for more information on supported video formats.

like image 52
Programmer Avatar answered Oct 02 '22 13:10

Programmer


Similar to what the other answers have been saying. You could use callbacks for when preparing and end of video states. Rather than using coroutines and yield return.

videoPlayer.loopPointReached += EndReached; videoPlayer.prepareCompleted += PrepareCompleted;  void PrepareCompleted(VideoPlayer vp) {     vp.Play(); }  void EndReached(VideoPlayer vp) {     // do something } 
like image 42
Groshh Avatar answered Oct 02 '22 14:10

Groshh