Использование нового Unity VideoPlayer и VideoClip API для воспроизведения видео

MovieTexture окончательно устарел после выпуска Unity 5.6.0b1 и нового API, который воспроизводит видео на обоих настольных и мобильных устройствах.

VideoPlayer и VideoClip может быть используется для воспроизведения видео и получения текстуры для каждого кадра, если это необходимо.

Мне удалось заставить видео работать, но не удалось воспроизвести звук, как из редактора на Windows 10. Кто-нибудь знает, почему звук не воспроизводится?

//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");
}

Ответ 1

Нашел проблему. Ниже приведен код FIXED, который воспроизводит видео и аудио:

//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");
}

Почему аудио не воспроизводится:

//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);

должен быть вызван до videoPlayer.Prepare(); не после него. Это заняло несколько часов эксперимента, чтобы найти, что это была проблема, с которой я столкнулся.


Застрял в "Подготовка видео"

Подождите 5 секунд после вызова videoPlayer.Prepare();, затем выйдите из цикла while.

Заменить:

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

с:

//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;
}

Это должно работать, но при загрузке видео может возникнуть буферизация. При использовании этого временного исправления мое предложение состоит в том, чтобы файл для ошибки с названием "videoPlayer.isPrepared always true", потому что это ошибка.

Некоторые люди также исправили это, изменив:

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

к

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

Воспроизвести видео из URL:

Заменить:

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

с:

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

затем Удалить:

public VideoClip videoToPlay; и videoPlayer.clip = videoToPlay;, поскольку они больше не нужны.

Воспроизвести видео из папки StreamingAssets:

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;

Все поддерживаемые видеоформаты:

  • ОГВ
  • vp8
  • WebM
  • мов
  • DV
  • mp4
  • m4v
  • мили на галлон
  • MPEG

Дополнительные поддерживаемые форматы видео в Windows:

  • AVI
  • АФС
  • WMF

Некоторые из этих форматов не работают на некоторых платформах. См. этот пост для получения дополнительной информации о поддерживаемых форматах видео.

Ответ 2

Как и другие ответы. Вы можете использовать обратные вызовы при подготовке и завершении состояний видео. Вместо использования сопрограмм и возврата возврата.

videoPlayer.loopPointReached += EndReached;
videoPlayer.prepareCompleted += PrepareCompleted;

void PrepareCompleted(VideoPlayer vp) {
    vp.Play();
}

void EndReached(VideoPlayer vp) {
    // do something
}

Ответ 3

К настоящему времени VideoPlayer должен быть обновлен достаточно, вам не нужно писать код, чтобы работать правильно. Вот настройки, которые, как мне показалось, имеют наиболее желательный эффект: Оптимальные настройки

Эти настройки:

Видеоплеер:

  • Play On Awake: True
  • Ожидание первого кадра: False
  • Режим аудиовыхода: Нет

Источник аудио:

  • Play On Awake: True

Не забывайте иметь VideoClip для VideoPlayer и AudioClip для AudioSource. Форматы файлов, которые, как мне показалось, работают лучше всего:.ogv для видео и .wav для аудио.