40 votes

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

MovieTexture est finalement déprécié après la sortie de la version 5.6.0b1 d'Unity et une nouvelle API qui lit les vidéos sur les appareils de bureau et mobiles est maintenant disponible.

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

J'ai réussi à faire fonctionner la vidéo mais je n'ai pas réussi à faire fonctionner l'audio à partir de l'éditeur sur Windows 10. Quelqu'un sait-il pourquoi l'audio ne fonctionne pas ?

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

0 votes

Avez-vous converti vous-même le poste à la communauté ?

0 votes

@Lestat Je ne l'ai pas fait mais je l'aurais fait si j'avais pu. Il semble que Martijn Pieters a fait puisque cette question était abusée par de nouveaux utilisateurs qui ne postaient que des questions comme réponse. Il a dû supprimer plusieurs de ces réponses/questions.

0 votes

J'ai créé un tutoriel vidéo sur l'utilisation de VideoPlayer. Voici le lien. youtu.be/nGA3jMBDjHk .

63voto

Programmer Points 69203

J'ai trouvé le problème. Voici le FIXE code 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. Il a fallu des heures d'expérience pour découvrir que c'était le problème que j'avais.


Vous êtes bloqué à "Préparer la vidéo" ?

Attendez 5 secondes après videoPlayer.Prepare(); est appelé, 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 il se peut que vous rencontriez des problèmes de mise en mémoire tampon lorsque la vidéo commence à être lue. Si vous utilisez ce correctif temporaire, je vous suggère d'enregistrer un bogue sous le titre "videoPlayer.isPrepared always true" car il s'agit d'un bogue.

Quelques personnes Je l'ai aussi corrigé en changeant :

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 Retirer :

public VideoClip videoToPlay; y 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

Formats vidéo supplémentaires pris en charge sous Windows :

  • avi
  • asf
  • wmf

Certains de ces formats ne fonctionnent pas sur certaines plateformes. Voir ce pour plus d'informations sur les formats vidéo pris en charge.

0 votes

J'ai essayé d'utiliser votre code pour lire une vidéo sur Unity 5.6.0b10 en ajoutant une vidéo .ogv. Mais lorsque j'appuie sur play, je ne vois que Preparing video sur la console. Et je ne sais pas non plus si le GameObject doit être RawImage, et ce qui doit être sur l'image ? Pouvez-vous m'aider à résoudre mon problème également ?

0 votes

@LuzanBaral "Et je suis aussi confus, est-ce que le GameObject doit être RawImage, et qu'est-ce qui doit être sur Image ?" Non. J'ai utilisé RawImage au lieu de la Image parce que c'est le moyen le plus efficace de le faire. Si vous utilisez le composant Image pour cela, vous devrez convertir le fichier vidéo en un fichier image. Texture a Sprite puis à Image . C'est cher.

0 votes

Notez que RawImage image; est uniquement utilisé pour afficher la texture de la vidéo. Créez-le en allant dans GameOjbect --> UI --> RawImage puis faites glisser le RawImage vers la variable image du script dans la réponse. Vous devez également faire glisser la vidéo à lire vers l'emplacement videoToPlay du script.

12voto

Groshh Points 71

Similaire à ce que les autres réponses ont dit. Vous pourriez utiliser des callbacks pour les états de préparation et de fin de vidéo. Plutôt que d'utiliser les coroutines et le yield return.

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

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

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

0 votes

Bien sûr, il y a quelques autres bugs audio que j'ai rencontrés. L'utilisation des méthodes de rappel m'a évité bien des maux de tête. En particulier si vous essayez de lire une vidéo à la suite d'une autre.

2 votes

Cela semble être une solution beaucoup plus raisonnable que les coroutines.

2voto

TarkaDaal Points 2961

J'ai utilisé la réponse de @Programmer pour lire des vidéos à partir d'une URL, mais je n'ai pas réussi à faire jouer de son. J'ai fini par trouver la réponse dans les commentaires d'un tutoriel YouTube.

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

videoPlayer.controlledAudioTrackCount = 1;

0 votes

Intéressant. Je n'ai pas eu de problèmes avec les audios des vidéos url mais cela sera utile à d'autres. Il pourrait s'agir d'un bogue dans l'éditeur.

-2voto

shieldgenerator7 Points 316

A présent, le VideoPlayer devrait être suffisamment mis à jour pour que vous n'ayez pas besoin d'écrire du code pour le faire fonctionner correctement. Voici les paramètres que j'ai trouvés pour avoir l'effet le plus souhaitable : Optimal Settings

Ces paramètres sont :

Lecteur vidéo :

  • Jouez sur Awake : Véritable
  • Attendez la première image : Faux
  • Mode de sortie audio : Aucun

Source audio :

  • Jouez sur Awake : Véritable

N'oubliez pas d'avoir un VideoClip pour le VideoPlayer et un AudioClip pour l'AudioSource. Les formats de fichiers qui fonctionnent le mieux sont .ogv pour la vidéo et .wav pour l'audio.

0 votes

"VideoPlayer devrait être assez mis à jour pour que vous n'ayez pas besoin d'écrire du code pour le faire fonctionner correctement" Pas vraiment. Vous devez encore écrire du code sur certaines plateformes et certaines (longues) vidéos, sinon la vidéo se fige. La solution consiste à appeler la fonction Prepare() ce qui ne peut être fait qu'à partir du code.

0 votes

@Programmer ok bon point. Je n'avais qu'une courte vidéo donc je n'avais pas besoin du code pour la faire jouer au démarrage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X