7 votes

Problèmes de préchargement des fichiers audio en Javascript

J'essaie de créer un schéma de préchargement d'image et d'audio pour un GameAPI sur lequel je travaille. Un fichier audio sera préchargé, et émettra un callback une fois qu'il sera terminé.

Le problème est que l'audio ne commence pas à se charger lors du chargement de pages lentes, mais fonctionne généralement au deuxième essai, probablement parce qu'il a été mis en cache et qu'il sait qu'il existe.

J'ai réduit le problème à la fonction audio.load(). La supprimer résout le problème, mais il est intéressant de noter que mon motorola droid a besoin de cette fonction.

Quelles sont les expériences que vous avez eues avec le préchargement audio HTML5 ?

Voici mon code. Oui, je sais que le fait de charger les images dans une fonction séparée pourrait causer une condition de course :)

var resourcesLoading = 0;

function loadImage(imgSrc) {
    //alert("Starting to load an image");
    resourcesLoading++;

    var image = new Image();
    image.src = imgSrc;

    image.onload = function() {
        //CODE GOES HERE
        //alert("A image has been loaded");
        resourcesLoading--;
        onResourceLoad();
    }
}

function loadSound(soundSrc) {
    //alert("Starting to load a sound");
    resourcesLoading++;

    var loaded = false;

    //var soundFile = document.createElement("audio");
    var soundFile = document.createElement("audio");
    console.log(soundFile);
    soundFile.autoplay = false;
    soundFile.preload = false;

    var src = document.createElement("source");
    src.src = soundSrc + ".mp3";
    soundFile.appendChild(src);

    function onLoad() {
        loaded = true;

        soundFile.removeEventListener("canplaythrough", onLoad, true);
        soundFile.removeEventListener("error", onError, true);

        //CODE GOES HERE
        //alert("A sound has been loaded");
        resourcesLoading--;
        onResourceLoad();
    }

    //Attempt to reload the resource 5 times
    var retrys = 4;

    function onError(e) {
        retrys--;

        if(retrys > 0) {
            soundFile.load();
        } else {
            loaded = true;

            soundFile.removeEventListener("canplaythrough", onLoad, true);
            soundFile.removeEventListener("error", onError, true);

            alert("A sound has failed to loaded");
            resourcesLoading--;
            onResourceLoad();
        }
    }

    soundFile.addEventListener("canplaythrough", onLoad, true);
    soundFile.addEventListener("error", onError, true);
}

function onResourceLoad() {
    if(resourcesLoading == 0)
        onLoaded();
}

Il est difficile de diagnostiquer le problème car il n'affiche aucune erreur et ne tombe en panne qu'occasionnellement.

6voto

Jeffrey Sweeney Points 3052

J'ai réussi à le faire fonctionner. La solution était assez simple en fait :

En gros, cela fonctionne comme suit :

channel.load();
channel.volume = 0.00000001;
channel.play();

Si cela n'est pas évident, le load indique aux navigateurs et aux appareils qui la prennent en charge de commencer à se charger, puis le son tente immédiatement de play avec le volume pratiquement à zéro. Ainsi, si le load Le fait que le son "doive" être joué suffit à déclencher une charge sur tous les appareils que j'ai testés.

Les load est peut-être redondante, mais compte tenu de l'incohérence de la mise en œuvre de l'audio, il n'y a probablement pas de mal à l'avoir.

Edit : Après avoir testé ceci sur Opera, Safari, Firefox, et Chrome, il semble que le réglage de l'attribut volume à 0, la ressource sera toujours préchargée.

2voto

AshleysBrain Points 11439

canplaythrough s'enflamme lorsque suffisamment de données ont été mises en mémoire tampon qu'il pourrait probablement être joué sans interruption jusqu'à la fin si vous commenciez à jouer lors de cet événement. L'élément HTML Audio est conçu pour la diffusion en continu, de sorte que le fichier peut ne pas avoir complètement terminé le téléchargement au moment où cet événement se déclenche.

À l'inverse, les images ne déclenchent leur événement qu'une fois qu'elles ont été entièrement téléchargées.

Si vous quittez la page et que le téléchargement de l'audio n'est pas terminé, le navigateur ne le met probablement pas en cache. En revanche, si le téléchargement est terminé, il est probablement mis en cache, ce qui explique le comportement que vous avez observé.

Je recommande le HTML5 AppCache pour s'assurer que les images et le son sont bien mis en cache.

1voto

Jörn Berkefeld Points 1465

L'AppCache, comme suggéré ci-dessus, pourrait être votre seule solution pour garder l'audio en cache d'une session de navigateur à l'autre (ce n'est pas ce que vous avez demandé, n'est-ce pas ?). Safari, par exemple, permet à l'utilisateur de modifier cette valeur dans les paramètres, mais la valeur par défaut est de 5 Mo - ce qui est à peine suffisant pour sauvegarder un grand nombre de chansons, surtout si d'autres sites web fréquentés par vos utilisateurs utilisent également AppCache. IE <10 ne prend pas non plus en charge AppCache.

0voto

Mr_Pouet Points 344

J'ai rencontré le même problème récemment, et mon astuce a été d'utiliser une simple requête ajax pour charger le fichier une seule fois (qui se termine dans le cache), puis de charger à nouveau le son directement à partir du cache et d'utiliser la liaison événementielle. canplaythrough .

L'utilisation Buzz.js comme bibliothèque audio HTML5, mon code est à peu près le suivant :

var self = this;
$.get(this.file_name+".mp3", function(data) {
    self.sound = new buzz.sound(self.file_name, {formats: [ "mp3" ], preload: true});
    self.sound.bind("error", function(e) {
        console.log("Music Error: " + this.getErrorMessage());
    });
    self.sound.decreaseVolume(20);
    self.sound.bind("canplaythrough",function(){ self.onSoundLoaded(self); }); 
});

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