I am working on an augmented reality application and was thrilled when Unitys new VideoPlayer was released, as it was much more compact and easier to handle than the Vuforia Video Playback example code that I was using beforehand.
However, when deploying to Android the videos are stuttering like crazy. The video freezes on random frames while audio (sometimes) presumes. Then a few frames are played again before another freeze happens. I tried different Android phones and had the same results. I tried different codecs, resolutions and enabling / disabling the “Transcode” option of the Editor.
The problem plagues me since I first tried the new VideoPlayer and was occuring when I used the old (non integrated) Vuforia version as well as with Unity 2017.2 or higher with the integrated Vuforia version.
On iOS devices (tested with iPhone 5 and newer devices) the videos play without any problem, same goes for playback in the editor. In contrast, even on current Android devices the problem does occur, which brought me to conclude that it is indeed Android-related.
Does anyone else face a similiar problem? Is this a known bug? I couldn’t find anything similar in the issue tracker but before opening a ticket I wanted to check if others faced similiar problems.
Details on the project
- Simple Image targets, videos are playing on a plane that hovers over a page
- Videos are switched at runtime (same player is used for 4 different clips)
- Altogether maybe 20 markers are present in the application, however I reproduced the problem with a minimalistic application and one marker + video
Code of the VideoManager
This section loads the video(s). The plane that the video plays on gets moved to the position in the scene that a plane with a thumbnail is displayed (above the marker).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
public class VideoManager : MonoBehaviour {
public enum VideoID {
VID_1, VID_2, VID_3, VID_4
};
private Transform initialParentTransform;
private VideoPlayer player;
private VideoID currentVideo;
private AudioSource audioSource;
private MeshRenderer mRenderer;
void Start () {
initialParentTransform = gameObject.transform.parent;
player = gameObject.GetComponent<VideoPlayer> ();
player.prepareCompleted += StartVideo;
player.errorReceived += LogError;
audioSource = gameObject.GetComponent<AudioSource> ();
mRenderer = gameObject.GetComponent<MeshRenderer> ();
}
public void PrepareVideo(VideoID id, VideoClip clip) {
currentVideo = id;
player.clip = clip;
// Prepare Audio
player.controlledAudioTrackCount = 1;
player.audioOutputMode = VideoAudioOutputMode.AudioSource;
player.EnableAudioTrack(0, true);
player.SetTargetAudioSource(0, audioSource);
player.Prepare ();
}
private void StartVideo(VideoPlayer p) {
p.Play ();
mRenderer.enabled = true;
}
private void LogError (VideoPlayer player, string error){
Debug.LogError (error);
}
public void StopVideo() {
mRenderer.enabled = false;
if (player != null) {
player.Stop ();
}
}
public void ResetPosition() {
if (initialParentTransform != null) {
gameObject.transform.parent = initialParentTransform;
gameObject.transform.position = Vector3.zero;
gameObject.transform.rotation = Quaternion.identity;
}
}
}