Правильный способ воспроизведения ‹аудио› + ‹видео› из Javascript

Я получаю разные результаты в Firefox и Chrome при использовании «аудио» и «видео» с preload = «none», а затем пытаюсь воспроизвести из Javascript.

Допустим, я использовал preload="auto" или preload="metadata":

audio.src = "filename";
audio.play();

Кажется, это отлично работает как в Firefox, так и в Chrome, но я хочу использовать preload = "none", а затем Chrome dossent play.

Итак, я пробую этот код с preload="none" :

audio.src = url;

audio.load();

audio.addEventListener('canplay', function(e) {
   audio.play(); // For some reason this dossent work in Firefox
}, false);

audio.play(); // Added this so Firefox would play

Я не знаю, правильный ли это способ.

Я использую: Firefox 20.0.1 Chrome 25.0.1364.172 м

Я сделал демонстрацию: http://netkoder.dk/test/test0217.html

Изменить:

Во втором аудиоплеере (на демонстрационной странице) кажется, что при использовании preload="none" вы должны использовать load(). Но правильно ли просто использовать play() сразу после load() или правильный способ использовать событие, чтобы дождаться загрузки файла перед его воспроизведением?

В третьем аудиоплеере кажется, что Firefox 20.0.1 поддерживает событие canplay правильно при использовании с addEventListener(), потому что он не запускает триггер после load(), он срабатывает после play(), а также срабатывает при очистке, хотя звук, который кажется быть так, как canplay должен работать. Использование .oncanplay действительно работает.

Таким образом, следующий код работает:

  function afspil2(url) {

     afspiller2.src = url;
     afspiller2.load(); // use load() when <audio> has preload="none"
     afspiller2.play();

  }

  function afspil3(url) {

     afspiller3.src = url;
     afspiller3.load(); // use load() when <audio> has preload="none"

     //afspiller3.addEventListener('canplay', function() { // For some reason this dossent work correctly in Firefox 20.0.1, its triggers after load() and when scrubbing
     //   afspiller3.play();
     //}, false);

     afspiller3.oncanplay = afspiller3.play(); // Works in Firefox 20.0.1

  }

Я обновил демо, чтобы включить изменения: http://netkoder.dk/test/test0217.html

Мой способ добавления addEventListener внутри функции afspil3() кажется хорошим, потому что при первом вызове функции код внутри addEventListener вызывается 1 раз. При втором вызове функции код внутри addEventListener вызывается 2 раза, затем 3 раза и так далее.


person scootergrisen    schedule 04.05.2013    source источник
comment
Можете ли вы привести полный пример того, где вы устанавливаете preload="none", и это не работает?   -  person user1091949    schedule 04.05.2013
comment
Демонстрация: netkoder.dk/test/test0217.html   -  person scootergrisen    schedule 04.05.2013


Ответы (2)


Это связано с тем, что в ваших тегах audio отсутствует обязательный атрибут src или теги <source>. Когда я добавил их в вашу демку, все 3 плеера сразу заработали и в Chrome, и в FF.

Кроме того, я недавно обнаружил, что src не может быть пустой строкой и впоследствии был изменен с помощью JS. Если есть причина, по которой вы не можете установить src в HTML, вашей лучшей альтернативой, IMO, является создание элементов audio с помощью Javascript:

var audio = new Audio();
audio.src = url;
audio.controls = true;
audio.preload = false;
// and so on

Изменить: Хорошо. Кажется, что в Chrome, когда HTML равен preload="none", необходимо вызвать load() перед воспроизведением, когда src изменено. Ваш второй audio не загружается предварительно, поэтому ваша функция должна быть такой:

  function afspil2(url) {
     afspiller2.src = url;
     afspiller2.load(); // add load call
     afspiller2.play();
  }

Потом вроде в файрфоксе надо ставить preload="auto"; при привязывании события к событию canplay, как в 3-ей функции.

  function afspil3(url) {
     afspiller3.src = url;
     afspiller3.preload = "auto";
     afspiller3.load();
     afspiller3.addEventListener('canplay', function(e) {
        this.play(); // For some reason this dossent work in Firefox
     }, false);
  }

Это кажется очень странным, но я проверял это несколько раз, и каждый раз он воспроизводился, если вызывался preload="auto", но не воспроизводился, если он не вызывался. Обратите внимание, что это не было необходимо для второго игрока, который также был preload="none" в теге HTML.

Наконец, Chrome ведет себя странно, если на странице несколько элементов <audio>. Для всех трех игроков перезагрузка страницы и нажатие на ссылку «большой электрон» будут воспроизводиться правильно.

Перезагрузка и последующее нажатие «Йода» на втором или третьем игроке ничего не даст, но будет играть для первого игрока. Но если первым сыграет лучший игрок любым способом — кнопкой воспроизведения или любой ссылкой — тогда две другие ссылки «Йода» внезапно заработают.

Кроме того, если вы нажмете 2-ю или 3-ю ссылку «Йода» сначала после перезагрузки, а затем щелкнете по верхнему игроку, ранее нажатый «Йода» (который ранее не играл) начнет играть сам по себе после того, как лучший игрок остановится. .

Достаточно сказать, что у них есть некоторые ошибки, которые нужно исправить.

person user1091949    schedule 04.05.2013
comment
Добавление src воспроизводит этот файл при запуске аудиоплеера, но мой код Javascript по-прежнему не работает после этого, если вы попытаетесь изменить источник звука по ссылкам над плеером. - person scootergrisen; 04.05.2013
comment
@scootergrisen Только что добавил правку. Человек, HTML5 <audio> просто еще не там, где он должен быть. На самом деле я пропустил ваш HTML-код через валидатор W3C, потому что подумал, что, возможно, несколько идентификаторов или что-то еще могут объяснить сумасшедшее поведение. Нет, ошибок нет. Просто он еще недостаточно развит. - person user1091949; 04.05.2013
comment
Ничего страшного, что он еще не разработан и работает не во всех браузерах, мне нравится жить на грани :D Но я хотел бы знать, как это сделать правильно. - person scootergrisen; 04.05.2013
comment
load() исправляет второй аудиоплеер. И да, у Chrome есть некоторые странные проблемы, но это не проблема, я просто хочу знать, как правильно писать код. Имеется в виду стандартный способ W3C, даже если он сейчас не работает должным образом в браузерах. Во всяком случае, я только что узнал, что Firefox поддерживает событие canplay при использовании с addEventlistener(), но поддерживает событие oncanplay. - person scootergrisen; 05.05.2013

На мой взгляд, правильным будет использование существующего решения, например http://mediaelementjs.com/.

Если вас действительно интересуют подробности о том, как лучше всего воспроизводить аудио и видео с помощью js, посмотрите на источник: https://github.com/johndyer/mediaelement/tree/master/src/js

https://github.com/johndyer/mediaelement/blob/master/src/js/me-mediaelements.js

person am_    schedule 05.05.2013
comment
Закомментированный раздел, начинающийся с того, что Chrome теперь поддерживает preload=none по адресу github.com/johndyer/mediaelement/blob/master/build/, так что, возможно, это намек на то, что некоторые проблемы все еще могут быть. Код, который я пишу, предназначен для того, чтобы другие люди могли видеть его на моем веб-сайте, поэтому я не хочу использовать такой код, как mediaelementjs. - person scootergrisen; 05.05.2013
comment
С mediaelementjs вы получаете полную поддержку даже старых браузеров, и большинство из них будет использовать это вместо того, чтобы пытаться изобретать велосипед. Вы должны по крайней мере добавить ссылку на свою страницу в mediaelementjs в качестве (imo: лучшей) альтернативы. - person am_; 05.05.2013
comment
Хорошо, что вы думаете, что это лучше, но это не то, что я ищу. Я хочу знать, как кодировать его самостоятельно снизу, и я не против, чтобы он не работал в старых браузерах или даже во всех новых. - person scootergrisen; 05.05.2013