Estou tentando fazer com que um arquivo de áudio seja reproduzido automaticamente no Safari em um iPad. Se eu for para a página usando o Safari no meu Mac, tudo bem. No iPad, a reprodução automática não funciona.
Estou tentando fazer com que um arquivo de áudio seja reproduzido automaticamente no Safari em um iPad. Se eu for para a página usando o Safari no meu Mac, tudo bem. No iPad, a reprodução automática não funciona.
Respostas:
ATUALIZAÇÃO: Este é um hack e não está mais funcionando no IOS 4.X e superior. Este funcionou no IOS 3.2.X.
Não é verdade. A Apple não quer reproduzir automaticamente vídeo e áudio no IPad por causa do alto volume de tráfego que você pode usar em redes móveis. Eu não usaria a reprodução automática para conteúdo online. Para sites HTML offline, é um ótimo recurso e é para isso que o usei.
Aqui está uma solução de "clique falso javascript": http://www.roblaplaca.com/examples/html5AutoPlay/
Copie e cole o código do site:
<script type="text/javascript">
function fakeClick(fn) {
var $a = $('<a href="#" id="fakeClick"></a>');
$a.bind("click", function(e) {
e.preventDefault();
fn();
});
$("body").append($a);
var evt,
el = $("#fakeClick").get(0);
if (document.createEvent) {
evt = document.createEvent("MouseEvents");
if (evt.initMouseEvent) {
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
el.dispatchEvent(evt);
}
}
$(el).remove();
}
$(function() {
var video = $("#someVideo").get(0);
fakeClick(function() {
video.play();
});
});
</script>
Esta não é minha fonte. Eu encontrei isso há algum tempo e testei o código em um IPad e IPhone com IOS 3.2.X.
Também gostaria de enfatizar que o motivo pelo qual você não pode fazer isso é uma decisão de negócios da Apple, não uma decisão técnica. A saber, não havia uma justificativa técnica racional para a Apple desativar o som dos aplicativos da web no iPod Touch. Esse é apenas um dispositivo WiFi, não um telefone que pode incorrer em tarifas caras de largura de banda, então esse argumento não tem mérito para esse dispositivo. Eles podem dizer que estão ajudando no gerenciamento da rede WiFi, mas quaisquer problemas com a largura de banda da minha rede WiFi são da minha conta, não da Apple.
Além disso, se o que realmente importava era evitar o consumo excessivo e indesejado de largura de banda, eles forneceriam uma configuração para permitir que os usuários optassem por sons de aplicativos da web. Além disso, eles fariam algo para impedir que os sites consumissem largura de banda equivalente por outros meios. Mas não existem tais restrições. Um site pode baixar arquivos enormes em segundo plano repetidamente, e a Apple não se importa com isso. E, finalmente, acredito que os sons podem ser baixados de qualquer maneira, então NENHUMA BANDA É SALVA DE VERDADE! A Apple simplesmente não permite que eles joguem automaticamente sem a interação do usuário, tornando-os inutilizáveis para jogos, o que, claro, é sua real intenção.
A Apple bloqueou o som porque começou a notar que os aplicativos HTML5 podem ser tão capazes quanto os aplicativos nativos, se não mais. Se você quer som em aplicativos da Web, precisa pressionar a Apple para que pare de ser anticompetitiva como a Microsoft. Não há nenhum problema técnico que possa ser corrigido aqui.
A Apple rejeita irritantemente muitos padrões da web HTML5 em seus dispositivos iOS, por uma variedade de razões comerciais. Em última análise, você não pode pré-carregar ou reproduzir automaticamente arquivos de som antes de um evento de toque, ele reproduz apenas um som por vez e não oferece suporte a Ogg / Vorbis. No entanto, encontrei uma solução alternativa interessante para permitir que você tenha um pouco mais de controle sobre o áudio.
<audio id="soundHandle" style="display:none;"></audio>
<script type="text/javascript">
var soundHandle = document.getElementById('soundHandle');
$(document).ready(function() {
addEventListener('touchstart', function (e) {
soundHandle.src = 'audio.mp3';
soundHandle.loop = true;
soundHandle.play();
soundHandle.pause();
});
});
</script>
Basicamente, você começa a reproduzir o arquivo de áudio no primeiro evento de toque e, em seguida, pausa imediatamente. Agora, você pode usar os comandos soundHandle.play () e soundHandle.pause () em todo o seu Javascript e controlar o áudio sem eventos de toque. Se você conseguir cronometrar perfeitamente, faça uma pausa logo após o som terminar. Então, da próxima vez que você reproduzi-lo novamente, ele retornará ao início. Isso não resolverá toda a bagunça que a Apple fez aqui, mas é uma solução.
A partir do iOS 4.2.1, nem o clique falso nem o truque .load () funcionarão para reproduzir áudio automaticamente em qualquer dispositivo iOS. A única opção que conheço é fazer com que o usuário realmente execute uma ação de clique e comece a reprodução no manipulador de eventos de clique sem envolver a chamada .play () em nada assíncrono (ajax, setTimeout etc.).
Alguém me diga se estou enganado. Eu tinha lacunas no iPad e no iPhone antes da atualização mais recente, e todas parecem ter sido fechadas.
<video>
4.2.1, verifiquei que, contanto que o .load()
então .play()
venha dentro de um manipulador de clique / toque síncrono , ele funcionará. Caso contrário, ele falha.
Confirmo que o áudio não está funcionando conforme descrito (pelo menos no iPad rodando 4.3.5). O problema específico é que o áudio não carrega em um método assíncrono (ajax, evento temporizador etc.), mas será reproduzido se tiver sido pré-carregado. O problema é que a carga deve estar em um evento disparado pelo usuário. Portanto, se você pode ter um botão para o usuário iniciar a reprodução, pode fazer algo como:
function initSounds() {
window.sounds = new Object();
var sound = new Audio('assets/sounds/clap.mp3');
sound.load();
window.sounds['clap.mp3'] = sound;
}
Em seguida, para reproduzi-lo, por exemplo, em uma solicitação ajax, você pode fazer
function doSomething() {
$.post('testReply.php',function(data){
window.sounds['clap.mp3'].play();
});
}
Não é a melhor solução, mas pode ajudar, especialmente sabendo que o culpado é a função de carregamento em um evento não disparado pelo usuário.
Edit: eu encontrei a explicação da Apple e ela afeta o iOS 4+: http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
Tente chamar o método .load () antes do método .play () na tag de áudio ou vídeo ... que será HTMLAudioElement ou HTMLVideoElement respectivamente. Essa era a única maneira que funcionaria no iPad para mim!
Parece-me que a resposta a esta pergunta está (pelo menos agora) claramente documentada nos documentos HTML5 do Safari :
Controle de downloads pelo usuário nas redes celulares
No Safari no iOS (para todos os dispositivos, incluindo iPad), onde o usuário pode estar em uma rede celular e ser cobrado por unidade de dados, o pré-carregamento e a reprodução automática são desativados. Nenhum dado é carregado até que o usuário o inicie. Isso significa que os métodos JavaScript play () e load () também estão inativos até que o usuário inicie a reprodução, a menos que o método play () ou load () seja acionado por ação do usuário. Em outras palavras, um botão Play iniciado pelo usuário funciona, mas um evento onLoad = "play ()" não.
Isso reproduz o filme: <input type="button" value="Play" onClick="document.myMovie.play()">
Isso não faz nada no iOS: <body onLoad="document.myMovie.play()">
Fiquei intrigado com isso enquanto desenvolvia um protótipo de aplicativo da web rápido no iOS4.2 (desenvolvimento de desenvolvimento). A solução é bastante simples. Observe que você não pode já ter a tag na sua página HTML, você realmente precisa inserir a tag no documento dinamicamente (observe que este exemplo usa o Protótipo 1.7 para alguns recursos extras do Javascript):
this.soundFile = new Element("audio", {id: "audio-1", src: "audio-1.mp3", controls: ""});
document.body.appendChild(this.soundFile);
this.soundFile.load();
this.soundFile.play();
Como você não configurou um controlador, não deve haver nenhuma necessidade de fazer nada complicado com CSS para ocultá-lo / posicioná-lo fora da tela.
Isso parece funcionar perfeitamente.
A Apple não suporta o padrão completamente, mas há uma solução alternativa. Sua justificativa é o congestionamento da rede celular, talvez porque você vá parar em páginas que reproduzem áudio aleatório. Este comportamento não muda quando um dispositivo liga wi-fi, talvez para consistência. A propósito, essas páginas geralmente são uma má ideia de qualquer maneira. Você não deve tentar colocar uma trilha sonora em todas as páginas da web. Isso é simplesmente errado. :)
o áudio html5 será reproduzido se for iniciado como resultado de uma ação do usuário. Carregar uma página não conta. Portanto, você precisa reestruturar seu aplicativo da web para ser um aplicativo tudo-em-uma-página. Em vez de um link que abre uma página que reproduz áudio, você precisa desse link para reproduzi-lo na página atual, sem uma mudança de página. Esta regra de "interação do usuário" se aplica aos métodos html5 que você pode chamar em um elemento de áudio ou vídeo. As chamadas retornam sem qualquer efeito se forem disparadas automaticamente no carregamento da página, mas funcionam quando chamadas de manipuladores de eventos.
Minha solução é disparar a partir de um evento de toque real em um menu anterior. Eles não o forçam a usar uma interface de jogador específica, é claro. Para meus propósitos, isso funciona bem. Se você não tem uma interface existente para usar, afaik você está ferrado. Talvez você possa tentar eventos de inclinação ou algo assim ...
Se você criar um elemento de áudio usando:
var a = new Audio("my_audio_file.wav");
E adicione um suspend
ouvinte de evento por meio de:
a.addEventListener("suspend", function () {console.log('suspended')}, false);
E, em seguida, carregue o arquivo no Safari móvel (iPad ou iPhone), você verá o 'suspenso' sendo registrado no console do desenvolvedor. De acordo com as especificações do HTML5, isso significa: "O agente do usuário intencionalmente não está buscando dados de mídia no momento, mas não tem todo o recurso de mídia baixado."
Chamar um a.load () subsequente, testar o evento "canplay" e, em seguida, usar a.play () parece um método adequado para acionar automaticamente o som.
Eu lidei com isso anexando um manipulador de eventos para todos os eventos para os quais você tem permissão para acionar áudio para o elemento de corpo, que aciona qualquer elemento de áudio html com reprodução automática para reproduzir uma vez.
var mobile = /iPad|iPhone|iPod|android/.test(navigator.userAgent) && !window.MSStream;
if (mobile) {
$('body').on('touchstart click doubleclick keydown', function() {
$("audio[autoplay='autoplay']").each(
function(){
this.play();
this.removeAttribute('autoplay');
});
});
}
Isso parece funcionar:
<html>
<title>
iPad Sound Test - Auto Play
</title>
</head>
<body>
<audio id="audio" src="mp3test.mp3" controls="controls" loop="loop">
</audio>
<script type="text/javascript">
window.onload = function() {
var audioPlayer = document.getElementById("audio");
audioPlayer.load();
audioPlayer.play();
};
</script>
</body>
</html>
Veja-o em ação aqui: http://www.johncoles.co.uk/ipad/test/1.html (arquivado)
A partir do iOS 4.2, isso não funciona mais. Desculpe.