Проблемы с предварительной загрузкой аудио в Javascript - PullRequest
6 голосов
/ 04 декабря 2011

Я пытаюсь создать кросс-устройство / браузер и схему предварительной загрузки звука для GameAPI, над которым я работаю. Звуковой файл будет предварительно загружен и выдаст обратный вызов после его завершения.

Проблема в том, что аудио не начинает загружаться при медленной загрузке страницы, но обычно будет работать со второй попытки, возможно потому, что оно кэшировало его и знает, что оно существует.

Я сузил его до функции audio.load (). Избавление от этого решает проблему, но, что интересно, моей дроиде-мотороле нужна эта функция.

Какие у вас были опыты с предварительной загрузкой аудио в HTML5?

Вот мой код. Да, я знаю, что загрузка изображений в отдельной функции может вызвать состояние гонки:)

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();
}

Трудно диагностировать проблему, поскольку она не показывает ошибок и дает сбой только изредка.

Ответы [ 4 ]

5 голосов
/ 06 января 2012

Я получил это работает. Решение было довольно простым на самом деле:

В принципе, это работает так:

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

Если это не очевидно, функция load сообщает браузерам и устройствам, которые ее поддерживают, начать загрузку, а затем звук сразу пытается play с volume практически на нуле. Поэтому, если функции load недостаточно, того факта, что для воспроизведения необходим звук, достаточно, чтобы вызвать нагрузку на всех протестированных мной устройствах.

Функция load сейчас может быть избыточной, но, исходя из несоответствия с реализацией аудио, вероятно, ее не помешает.

Редактировать: После проверки этого в Opera, Safari, Firefox и Chrome, похоже, что установка volume в 0 все равно будет предварительно загружать ресурс.

2 голосов
/ 04 декабря 2011

canplaythrough срабатывает, когда достаточно данных, буферизованных , что, вероятно, оно может воспроизводиться без остановки до конца, если вы начали играть на этом событии.Элемент HTML Audio предназначен для потоковой передачи, поэтому файл может не полностью завершить загрузку к моменту запуска этого события.

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

Если вы ушли со страницы, а аудио еще не полностью загружено, браузер, вероятно, вообще не кеширует его.Однако, если он полностью завершил загрузку, он, вероятно, кэшируется, что объясняет поведение, которое вы видели.

Я бы порекомендовал HTML5 AppCache , чтобы убедиться, что изображения и аудиоконечно кешируется.

1 голос
/ 05 декабря 2011

AppCache, как предложено выше, может быть вашим единственным решением для хранения кэшированного аудио от одного сеанса браузера к другому (это не то, что вы просили, верно?). но имейте в виду ограниченное количество места, которое предлагают некоторые браузеры. Например, Safari позволяет пользователю изменять это значение в настройках, но по умолчанию оно составляет 5 МБ, что вряд ли достаточно для сохранения группы песен, особенно если другие веб-сайты, которые посещают ваши пользователи, также используют AppCache. Также IE <10 не поддерживает AppCache. </p>

0 голосов
/ 18 декабря 2013

Хорошо, поэтому недавно я столкнулся с той же проблемой, и моя хитрость заключалась в том, чтобы использовать простой ajax-запрос, чтобы загрузить файл полностью один раз (который заканчивается в кэш), а затем снова загрузить звук непосредственно из кеша и использовать привязка события canplaythrough.

Используя Buzz.js в качестве моей аудиобиблиотеки HTML5, мой код выглядит примерно так:

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); }); 
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...