web-dev-qa-db-fra.com

Utilisation des nouvelles API Unity VideoPlayer et VideoClip pour lire des vidéos

MovieTexture est finalement obsolète après la publication de Unity 5.6.0b1 et la sortie d'une nouvelle API permettant de lire des vidéos sur les appareils de bureau et mobiles.

VideoPlayer et VideoClip peut être utilisé pour lire une vidéo et récupérer une texture pour chaque image si nécessaire.

J'ai réussi à faire fonctionner la vidéo mais je n'ai pas pu lire correctement l'audio dans l'éditeur de Windows 10. Quelqu'un sait pourquoi l'audio n'est pas lu?

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

Trouvé le problème. Ci-dessous, le code CORRIG&EACUTE; qui lit la vidéo et l'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");
}

Pourquoi Audio ne jouait pas:

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

doit être appelé avant videoPlayer.Prepare(); pas après. Cela a pris des heures d’expérience pour trouver que c’était le problème que j’avais.


Stuck at "Préparation de la vidéo"?

Attendez 5 secondes après l'appel de videoPlayer.Prepare();, puis quittez la boucle while. 

Remplacer:

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

avec:

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

Cela devrait fonctionner, mais la mise en mémoire tampon risque de se produire lorsque la lecture de la vidéo commence. Lors de l'utilisation de ce correctif temporaire, ma suggestion est de créer un bogue portant le titre "videoPlayer.isPrepared toujours vrai" car il s'agit d'un bogue.

Quelques personnes ont également corrigé le problème en modifiant:

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

à

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

Lire la vidéo à partir de l'URL:

Remplacer:

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

avec:

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

puis supprimer:

public VideoClip videoToPlay; et videoPlayer.clip = videoToPlay; car ils ne sont plus nécessaires. 

Lire la vidéo à partir du dossier 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;

Tous les formats vidéo pris en charge:

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

Extra formats vidéo pris en charge sous Windows:

  • avi
  • asf
  • wmf

Certains de ces formats ne fonctionnent pas sur certaines plates-formes. Voir this post pour plus d'informations sur les formats vidéo pris en charge.

54
Programmer

Semblable à ce que les autres réponses ont dit. Vous pouvez utiliser des rappels lors de la préparation et de la fin des états vidéo. Plutôt que d’utiliser des coroutines et d’obtenir un rendement.

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

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

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

J'ai utilisé la réponse de @Programmer pour lire des vidéos à partir d'une URL, mais je ne pouvais obtenir aucun son. Finalement, j'ai trouvé la réponse dans les commentaires d'un didacticiel YouTube.

Pour que l'audio soit lu pour un film chargé via une URL, vous devez ajouter la ligne suivante avant l'appel à EnableAudioTrack:

videoPlayer.controlledAudioTrackCount = 1;
1
TarkaDaal