Arquivos de áudio de reprodução automática em um iPad com HTML5

88

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.

milhasmeow
fonte
1
Esta não é uma resposta, mas apenas uma observação. Quando coloquei o WireShark na minha conexão com o iPad, percebi que ele não reproduzia automaticamente, mas mesmo assim é feito o download do arquivo Wave. O primeiro Get HTTP pede apenas os primeiros 2 bytes do arquivo, mas então o iPad pede o resto do arquivo Wave em mais algumas solicitações Get. O que é ainda mais estranho é que quando você clica no botão 'Play' do componente de áudio, o iPad recarrega o arquivo Wave novamente.
Javamann

Respostas:

34

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.

Fa11enAngel
fonte
1
Aqui está outra solução alternativa: codeblog.co/getting-autoplay-working-on-ios Acabei de verificar que isso funciona no iPad com iOS 3.2.
Ciryon,
49
Não perca tempo com isso, pois ele não funciona mais com iOS 4+
jcampbell1
104

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.

Rick M
fonte
Não é o mesmo para o Android?
Rune Jeppesen de
1
@Rune Jeppesen Não. Eu tenho um aplicativo PhoneGap / Cordova que tem um reprodutor de áudio e funciona perfeitamente no Android. A única razão pela qual cheguei a este tópico aqui no StackOverflow são as restrições do iOS em relação à reprodução de áudio.
Ulysses Alves
Agora, o Chrome para Android e para desktop tem uma política semelhante ao iOS
Ore4444
28

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.

Kaleazy
fonte
Ainda não tentei, mas se realmente funcionar, é brilhante.
courtimas
3
Surpreso que mais pessoas não estão interessadas nisso.
aoeu256
Ainda está funcionando? Parece que consigo fazer isso funcionar ...
zillaofthegods
@MastaBaba Esta deve ser a resposta aceita. Por quê? Ele não responde à pergunta, pois é isso que o OP pede: Estou tentando fazer com que um arquivo de áudio seja reproduzido automaticamente no Safari e esta resposta não ajuda na reprodução automática.
estreia em
23

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.

David Gouldin
fonte
5
Posso verificar se o código estava funcionando para reprodução automática de áudio sem a intervenção do usuário no iPad e no iPod touch, antes de 4.2.1. Acabei de atualizar meu iPad para 4.2.1 hoje (no meio do teste do meu pré-carregador de áudio no momento) e observei com horror quando ele simplesmente parou de funcionar.
Jason Kester
2
No <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.
N Rohler de
1
Parece que o controle programático de elementos de mídia (áudio e vídeo) é habilitado após a interação do usuário por elemento de mídia . Ou seja, se você tiver os elementos de áudio A e B e iniciar a reprodução de A via código dentro do escopo de um manipulador de eventos de clique (ou toque), ele funciona. Mas isso não significa que você pode iniciar posteriormente a reprodução de B fora do escopo de um manipulador de eventos de clique. Trate os elementos de mídia no iOS como um singleton e troque as fontes em uma instância, em vez de multiplicar as instâncias por fontes.
Tim Erickson
9

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

Jacob Mouka
fonte
Esta é a resposta Gold. Você pode preencher objetos de sons com vários sons. E depois de chamar ajax em casos de sucesso / erro, toque o que quiser. Funciona para mim em todos os dispositivos! Big tnx !!!
Andris,
7

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!

Brian Brown
fonte
De acordo com os documentos do desenvolvedor da apple, nem .load nem .play funcionarão, exceto quando acionados por um usuário.
Jeffrey Van Alstine
5

A reprodução automática não funciona no iPad ou iPhone para as tags de vídeo ou áudio. Esta é uma restrição definida pela Apple para economizar largura de banda dos usuários.

Andrew
fonte
5

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()">

Adrian
fonte
2

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.

Jon Jardine
fonte
2

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.

bmidgley
fonte
1

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 ...

Luke Stanley
fonte
1

Se você criar um elemento de áudio usando:

var a = new Audio("my_audio_file.wav");

E adicione um suspendouvinte 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.

Vince
fonte
Tentei fazer isso, mas não parece funcionar. Qualquer atualização? sandbox.coolaj86.info/html5-audio-tag-ios4.html
coolaj86
0

Funciona com jQuery, testado em Ipad v.5.1.1

$('video').get(0).play();

Você deve anexar / remover o elemento de vídeo da página.

Adrian
fonte
3
Não funciona no iPad 1 iOS 5.1.1 ... embora funcione no iPod 6.0 e iPhone
morgan_il
0

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');
            });
    });
}
Andrew Hancox
fonte
0

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.

John Coles
fonte
@ NisseEngström Parece-me que o arquivo mp3 também não está arquivado, então a edição do link do arquivo é bastante discutível.
Adeus StackExchange
@FrankerZ: Existe um link mp3? Eu senti falta disso. Obrigado.
Nisse Engström