Need help with issues using the VideoPlayer released in Unity 5.6
The goal for what I am looking to do is the following:
1) I need to load video from an URL on iOS using Prepare(). Once prepared, I will enable a play button for the user to play video on iOS
2) I need audio to play from the video.
3) I need to be able to rotate the video and resize based on device orientation.
After several tries, I can't seem to get consistent behavior from the VideoPlayer in any way. My current state of my script is that the video plays automatically after my video fires the prepared event, regardless if I call play on the video player component or not. Also audio will not play if I set the audio to Direct or AudioSource. I currently am using AudioSource as I read that it should always work, which it doesn't.
So I do not want to the video to play automatically but just enable a "Play" button, and I want audio to play. I do have fullscreen video with rotation working however. My current setup in my screen is I have a Canvas, with a RawImage component as its child. I attached my script TestVideo.cs to the RawImage component. The RectTransform of the RawImage is set to Middle Center with a width and height of 10. This gets resized with my methods depending upon device orientation and video orientation.
I attach the VideoPlayer component and the AudioPlayer Component in my TestVideo.cs script at runtime.
Here is the TestVideo.cs for reference:
public class TestVideo : MonoBehaviour {
private bool _rotatedLeftBol;
private bool _rotatedRightBol;
private VideoPlayer _vidPlayer;
private GameObject _gameObject;
private RawImage _videoRawImg;
private RectTransform _rectTrans;
private Vector3 _rotatedLeftV3 = new Vector3(0,0,-90f);
private Vector3 _rotatedRightV3 = new Vector3(0,0,90f);
//Hardcoding this but can get it from AppConfigMod
private Vector2 _refResV2 = new Vector2(320f,550f);
private bool _isVideoLandscapeBol;
AudioSource _audioSource;
void Start ()
{
_gameObject = gameObject;
_rectTrans = _gameObject.GetComponent<RectTransform>();
_videoRawImg = _gameObject.GetComponent<RawImage>();
_vidPlayer = _gameObject.AddComponent<VideoPlayer>();
_vidPlayer.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
_vidPlayer.renderMode = VideoRenderMode.RenderTexture;
_vidPlayer.targetTexture = _videoRawImg.texture as RenderTexture;
_audioSource = _gameObject.AddComponent<AudioSource>();
//Disable Play on Awake for both Video and Audio
_vidPlayer.playOnAwake = false;
_audioSource.playOnAwake = false;
//Set Audio Output to AudioSource
_vidPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
//Assign the Audio from Video to AudioSource to be played
_vidPlayer.EnableAudioTrack(0, true);
_vidPlayer.SetTargetAudioSource(0, _audioSource);
_vidPlayer.prepareCompleted += Prepared;
_vidPlayer.Prepare();
}
void Prepared(UnityEngine.Video.VideoPlayer _vidPlayer) {
Debug.Log("Prepare complete!");
_isVideoLandscapeBol = (_vidPlayer.texture.width > _vidPlayer.texture.height);
if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft || (Input.deviceOrientation == DeviceOrientation.LandscapeRight))
{
_resizeVideoImgToFullScreenLandscapeOrientation();
}
else
{
_resizeVideoImgToFullScreenPortraitOrientation();
}
_enablePlayBtn();
// audioSource.Play();
// _vidPlayer.Play();
}
private void _enablePlayBtn()
{
Debug.Log("PLAY BUTTON SHOULD ENABLE HERE!");
}
void Update ()
{
if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft)
{
if (!_rotatedLeftBol)
{
Log.Message("Device is LANDSCAPE LEFT!!!");
_rotatedLeftBol = true;
_resizeVideoImgToFullScreenLandscapeOrientation();
_rotateVideo(_rotatedLeftV3);
}
}
else if (Input.deviceOrientation == DeviceOrientation.LandscapeRight)
{
if (!_rotatedRightBol)
{
Log.Message("Device is LANDSCAPE RIGHT!!!");
_resizeVideoImgToFullScreenLandscapeOrientation();
_rotatedRightBol = true;
_rotateVideo(_rotatedRightV3);
}
}
else if (Input.deviceOrientation == DeviceOrientation.Portrait)
{
if (_rotatedLeftBol)
{
_resizeVideoImgToFullScreenPortraitOrientation();
Log.Message("Device is PORTRAIT!!!");
_rotatedLeftBol = false;
_rotateVideo(Vector3.zero);
}
else if (_rotatedRightBol)
{
_resizeVideoImgToFullScreenPortraitOrientation();
Log.Message("Device is PORTRAIT!!!");
_rotatedRightBol = false;
_rotateVideo(Vector3.zero);
}
}
}
private void _resizeVideoImgToFullScreenPortraitOrientation()
{
// float __videoWidthFlt = ((float)_vidPlayer.texture.width > _refResV2.x) ? _refResV2.x : (float)_vidPlayer.texture.width;
float __videoWidthFlt;
if (_isVideoLandscapeBol)
{
__videoWidthFlt = ((float)_vidPlayer.texture.width >= _refResV2.x) ? _refResV2.x : (float)_vidPlayer.texture.width;
}
else
{
__videoWidthFlt = ((float)_vidPlayer.texture.width <= _refResV2.x) ? _refResV2.x : (float)_vidPlayer.texture.width;
}
_rectTrans.sizeDelta = new Vector2(__videoWidthFlt, __videoWidthFlt);
}
private void _resizeVideoImgToFullScreenLandscapeOrientation()
{
float __videoHeightFlt;
if (_isVideoLandscapeBol)
{
__videoHeightFlt = ((float)_vidPlayer.texture.height <= _refResV2.y) ? _refResV2.y : (float)_vidPlayer.texture.height;
}
else
{
__videoHeightFlt = ((float)_vidPlayer.texture.height >= _refResV2.y) ? _refResV2.y : (float)_vidPlayer.texture.height;
}
_rectTrans.sizeDelta = new Vector2(__videoHeightFlt, __videoHeightFlt);
}
private void _rotateVideo(Vector3 __v3)
{
LeanTween.rotateLocal(gameObject, __v3, 0.25f).setEase(LeanTweenType.easeInOutCirc);
}
}
So I created two more tests. The first one, I can get audio to play by creating a RawImage Component on the canvas and adding the VideoComponent to the RawImage component in the Editor instead of at runtime. But the video won't play nor will the prepareCompleted event fire at all. This version I can get audio to play using Direct mode or the AudioSource mode by adding an audio source to the component and referencing that in the VideoPlayer. But as I stated before no video.
The second test, I can get both video and audio working but I cannot use the UGUI system. I have game object with a quad mesh and a meshRenderer on it. I set the renderMode in VideoPlayer to MaterialOverride and reference the attached MeshRenderer. But even with this version there are two issues:
1) prepareComplete still does not fire so I have to set video to play onAwake which I do not want and 2) This is not using the UGUI system which is extremely ideal for me by how I have my project setup.
I know this is long but I am trying to put all possibilities out there in case I forgot something or am doing something completely stupid. I feel though that the VideoComponent is still very buggy as like the question states, I can't get any consistency out of it depending on how it's implemented even though I am using the BuckBunny video for all of my tests.
Answer by Adquizition · May 17, 2017 at 06:18 PM
With Unity's patch release version 5.6.0p4 fixed the prepareComplete issue. I can also use the UGUI system properly to display my video. As far as the video playing automatically once prepareComplete is fired, I just call Stop() on the video player to fix that issue. Not sure if that is working as intended or not, but I was able to get it to do what I wanted by calling Stop() and then calling Play() when a play button was clicked.
Your answer
Follow this Question
Related Questions
VideoPlayer Crash on iOS Launch 0 Answers
VideoPlayer doesn't work on iOS 0 Answers
Append to an Xcode .mm file from a PostProcess functions? 0 Answers