Tự động phát tệp âm thanh trên iPad với HTML5


88

Tôi đang cố lấy tệp âm thanh để tự động phát trong Safari trên iPad. Nếu tôi truy cập trang bằng Safari trên máy Mac thì không sao cả. Trên iPad, tính năng tự động phát không hoạt động.


1
Đây không phải là một câu trả lời mà chỉ là một quan sát. Khi tôi đặt WireShark vào kết nối của mình với iPad, tôi nhận thấy rằng nó sẽ không tự động phát nhưng vẫn được tải xuống tệp Wave. HTTP Get đầu tiên chỉ yêu cầu 2 byte đầu tiên của tệp nhưng sau đó iPad yêu cầu phần còn lại của tệp Wave trong một số yêu cầu Get khác. Điều kỳ lạ hơn nữa là khi bạn nhấp vào nút 'Phát' của thành phần Âm thanh, iPad sẽ tải lại tệp Sóng.
Javamann

Câu trả lời:


34

CẬP NHẬT: Đây là một bản hack và nó không hoạt động nữa trên IOS 4.X trở lên. Cái này hoạt động trên IOS 3.2.X.

Nó không đúng. Apple không muốn tự động phát video và âm thanh trên IPad vì lưu lượng truy cập lớn mà bạn có thể sử dụng trên các mạng di động. Tôi sẽ không sử dụng tính năng tự động phát cho nội dung trực tuyến. Đối với các trang web HTML ngoại tuyến, đó là một tính năng tuyệt vời và đó là những gì tôi đã sử dụng nó.

Đây là giải pháp "nhấp chuột giả mạo javascript": http://www.roblaplaca.com/examples/html5AutoPlay/

Sao chép & dán mã từ trang web:

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

Đây không phải là nguồn của tôi. Tôi đã tìm thấy điều này một thời gian trước đây và đã kiểm tra mã trên IPad và iPhone với IOS 3.2.X.


1
Đây là một giải pháp khác: codeblog.co/getting-autoplay-working-on-ios Tôi vừa xác minh rằng điều này hoạt động trên iPad với iOS 3.2.
Ciryon

49
Đừng lãng phí thời gian của bạn với điều này vì nó không còn làm việc với iOS 4+
jcampbell1

106

Tôi cũng muốn nhấn mạnh rằng lý do bạn không thể làm điều này là một quyết định kinh doanh của Apple, không phải một quyết định kỹ thuật. Nói một cách dí dỏm, không có lý do kỹ thuật hợp lý nào để Apple tắt âm thanh từ các ứng dụng web trên iPod Touch. Đó chỉ là thiết bị WiFi, không phải điện thoại có thể phải trả phí băng thông đắt đỏ, vì vậy lập luận đó không có giá trị cho thiết bị đó. Họ có thể nói rằng họ đang giúp quản lý mạng WiFi, nhưng bất kỳ vấn đề nào với băng thông trên mạng WiFi của tôi là mối quan tâm của tôi, không phải của Apple.

Ngoài ra, nếu điều họ thực sự quan tâm là ngăn chặn việc tiêu thụ băng thông quá mức, không mong muốn, họ sẽ cung cấp một cài đặt để cho phép người dùng chọn sử dụng âm thanh ứng dụng web. Ngoài ra, họ sẽ làm điều gì đó để hạn chế các trang web tiêu thụ băng thông tương đương bằng các phương tiện khác. Nhưng không có hạn chế như vậy. Một trang web có thể tải xuống liên tục các tệp khổng lồ trong nền và Apple có thể ít quan tâm đến điều đó hơn. Và cuối cùng, tôi tin rằng dù sao đi nữa, âm thanh cũng có thể được tải xuống, vì vậy KHÔNG CÓ RĂNG CỨNG ĐƯỢC TIẾT KIỆM THỰC SỰ! Apple chỉ không cho phép chúng chơi tự động mà không có sự tương tác của người dùng, khiến chúng không thể sử dụng được cho các trò chơi, tất nhiên đó là mục đích thực sự của chúng.

Apple đã chặn âm thanh vì họ bắt đầu nhận thấy rằng các ứng dụng HTML5 có thể có khả năng tương đương với các ứng dụng gốc, nếu không muốn nói là hơn thế. Nếu bạn muốn có âm thanh trong Ứng dụng web, bạn cần vận động Apple ngừng phản đối cạnh tranh như Microsoft. Không có vấn đề kỹ thuật nào có thể được khắc phục ở đây.


Nó không giống với Android?
Rune Jeppesen

1
@Rune Jeppesen Không. Tôi có ứng dụng PhoneGap / Cordova có trình phát âm thanh và nó hoạt động hoàn hảo trên Android. Lý do duy nhất khiến tôi tiếp cận chủ đề này ở đây trong StackOverflow là các hạn chế của iOS về phát lại âm thanh.
Ulysses Alves

Giờ đây, Chrome dành cho Android và dành cho máy tính để bàn có chính sách tương tự như iOS
Ore4444

29

Apple từ chối một cách khó chịu nhiều tiêu chuẩn web HTML5 trên các thiết bị iOS của họ, vì nhiều lý do kinh doanh. Cuối cùng, bạn không thể tải trước hoặc tự động phát các tệp âm thanh trước một sự kiện chạm, nó chỉ phát một âm thanh tại một thời điểm và không hỗ trợ Ogg / Vorbis. Tuy nhiên, tôi đã tìm thấy một giải pháp tiện lợi để cho phép bạn kiểm soát nhiều hơn một chút đối với âm thanh.

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

Về cơ bản, bạn bắt đầu phát tệp âm thanh trong sự kiện chạm đầu tiên, sau đó bạn tạm dừng nó ngay lập tức. Giờ đây, bạn có thể sử dụng các lệnh soundHandle.play () và soundHandle.pause () trong suốt Javascript của mình và điều khiển âm thanh mà không cần sự kiện chạm. Nếu bạn có thể căn thời gian hoàn hảo, chỉ cần tạm dừng ngay sau khi âm thanh kết thúc. Sau đó, lần sau khi bạn chơi lại, nó sẽ lặp lại từ đầu. Điều này sẽ không giải quyết được tất cả những rắc rối mà Apple đã gây ra ở đây, nhưng đó là một giải pháp.


Tôi chưa thử điều này, nhưng nếu nó thực sự hoạt động, điều này thật tuyệt vời.
Courtimas

3
Thật ngạc nhiên khi nhiều người không quan tâm đến điều này.
aoeu256

Cái này vẫn hoạt động chứ? Tôi có thể có vẻ để có thể có được điều này với chức năng ...
zillaofthegods

@MastaBaba Đây phải là câu trả lời được chấp nhận. Tại sao? Nó không trả lời câu hỏi, vì đây là những gì OP yêu cầu: Tôi đang cố lấy một tệp âm thanh để tự động phát trong Safari và câu trả lời này không giúp ích cho tự động phát.
debute

23

Kể từ iOS 4.2.1, cả nhấp chuột giả hay thủ thuật .load () sẽ không hoạt động để tự động phát âm thanh trên bất kỳ thiết bị iOS nào. Tùy chọn duy nhất mà tôi biết là để người dùng thực sự thực hiện hành động nhấp chuột và bắt đầu phát lại trong trình xử lý sự kiện nhấp chuột mà không gói lệnh gọi .play () trong bất kỳ thứ gì không đồng bộ (ajax, setTimeout, v.v.).

Ai đó làm ơn cho tôi biết nếu tôi nhầm lẫn. Tôi đã có lỗ hổng làm việc cho cả iPad và iPhone trước bản cập nhật gần đây nhất và tất cả chúng đều có vẻ như đã bị đóng.


5
Tôi có thể xác minh rằng tôi có mã hoạt động để tự động phát âm thanh mà không cần sự can thiệp của người dùng trên cả iPad và iPod touch, trước 4.2.1. Tôi vừa cập nhật iPad của mình lên 4.2.1 hôm nay (đang trong quá trình thử nghiệm trình tải trước âm thanh của tôi khi nó xảy ra) và kinh hoàng nhìn nó đơn giản là ngừng hoạt động.
Jason Kester

2
Với <video>4.2.1, tôi đã xác minh rằng miễn là .load()sau đó .play()có trong trình xử lý nhấp / chạm đồng bộ , nó sẽ hoạt động. Nếu không, nó không thành công.
N Rohler

1
Có vẻ như tính năng kiểm soát theo chương trình của các phần tử phương tiện (âm thanh và video) được bật sau khi người dùng tương tác với mỗi phần tử phương tiện . Tức là nếu bạn có phần tử âm thanh A và B và bạn bắt đầu phát lại A thông qua mã trong phạm vi của trình xử lý sự kiện nhấp (hoặc chạm), nó sẽ hoạt động. Nhưng điều đó không có nghĩa là sau này bạn có thể bắt đầu phát lại B bên ngoài phạm vi của trình xử lý sự kiện nhấp chuột. Xử lý các phần tử phương tiện trong iOS như một đơn vị và hoán đổi các nguồn trên một phiên bản thay vì nhân các phiên bản với các nguồn.
Tim Erickson

10

Tôi xác nhận rằng âm thanh không hoạt động như mô tả (ít nhất là trên iPad chạy 4.3.5). Vấn đề cụ thể là âm thanh sẽ không tải trong một phương thức không đồng bộ (ajax, sự kiện hẹn giờ, v.v.) nhưng nó sẽ phát nếu được tải trước. Vấn đề là tải phải được thực hiện trên một sự kiện do người dùng kích hoạt. Vì vậy, nếu bạn có thể có một nút để người dùng bắt đầu chơi, bạn có thể làm điều gì đó như:

function initSounds() {
    window.sounds = new Object();
    var sound = new Audio('assets/sounds/clap.mp3');
    sound.load();
    window.sounds['clap.mp3'] = sound;
}

Sau đó, để chơi nó, ví dụ như trong một yêu cầu ajax, bạn có thể làm

function doSomething() {
    $.post('testReply.php',function(data){
        window.sounds['clap.mp3'].play();
    }); 
}

Không phải là giải pháp tốt nhất, nhưng nó có thể hữu ích, đặc biệt khi biết thủ phạm là hàm tải trong một sự kiện không do người dùng kích hoạt.

Chỉnh sửa: Tôi đã tìm thấy lời giải thích của Apple và nó ảnh hưởng đến iOS 4+: http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html


Đây là câu trả lời Vàng. Bạn có thể điền vào đối tượng âm thanh với nhiều âm thanh. Và sau cuộc gọi ajax về các trường hợp thành công / lỗi, hãy chơi bất kỳ trò chơi nào bạn muốn. Hoạt động cho tôi trên mọi thiết bị! Tnx lớn !!!
Andris

7

Thử gọi phương thức .load () trước phương thức .play () trên thẻ âm thanh hoặc video ... sẽ là HTMLAudioElement hoặc HTMLVideoElement tương ứng. Đó là cách duy nhất nó hoạt động trên iPad đối với tôi!


Theo tài liệu của nhà phát triển apple, cả .load và .play đều không hoạt động trừ khi được kích hoạt bởi người dùng.
Jeffrey Van Alstine

5

Tự động phát không hoạt động trên iPad hoặc iPhone đối với video hoặc thẻ âm thanh. Đây là một hạn chế được đặt ra bởi Apple để tiết kiệm băng thông của người dùng.


5

Đối với tôi, dường như câu trả lời cho câu hỏi này (ít nhất là bây giờ) được ghi lại rõ ràng trên tài liệu HTML5 của Safari :

Kiểm soát người dùng tải xuống qua mạng di động

Trong Safari trên iOS (cho tất cả các thiết bị, bao gồm cả iPad), nơi người dùng có thể đang sử dụng mạng di động và bị tính phí cho mỗi đơn vị dữ liệu, tính năng tải trước và tự động phát bị tắt. Không có dữ liệu nào được tải cho đến khi người dùng bắt đầu nó. Điều này có nghĩa là các phương thức JavaScript play () và load () cũng không hoạt động cho đến khi người dùng bắt đầu phát lại, trừ khi phương thức play () hoặc load () được kích hoạt bởi hành động của người dùng. Nói cách khác, nút Play do người dùng khởi tạo hoạt động, nhưng sự kiện onLoad = "play ()" thì không.

Điều này đóng phim: <input type="button" value="Play" onClick="document.myMovie.play()">

Điều này không có gì trên iOS: <body onLoad="document.myMovie.play()">


2

Đã phân vân về điều này trong khi phát triển một ứng dụng web nguyên mẫu nhanh trong iOS4.2 (bản dựng dành cho nhà phát triển). Giải pháp thực sự khá đơn giản. Lưu ý rằng dường như bạn không thể có thẻ trong trang HTML của mình, bạn thực sự cần phải chèn thẻ vào tài liệu một cách động (lưu ý rằng ví dụ này sử dụng Prototype 1.7 cho một số Javascript bổ sung nhanh):

this.soundFile = new Element("audio", {id: "audio-1", src: "audio-1.mp3", controls: ""});
document.body.appendChild(this.soundFile);
this.soundFile.load();
this.soundFile.play();

Vì bạn chưa đặt bộ điều khiển, nên không cần phải làm bất kỳ điều gì phức tạp với CSS để ẩn nó / định vị nó ngoài màn hình.

Điều này dường như hoạt động hoàn hảo.


2

Apple không hỗ trợ tiêu chuẩn này hoàn toàn, nhưng có một cách giải quyết. Lời biện minh của họ là do tắc nghẽn mạng di động, có thể vì bạn sẽ truy cập vào các trang phát âm thanh ngẫu nhiên. Hành vi này không thay đổi khi thiết bị bật Wi-Fi, có thể là do tính nhất quán. Nhân tiện, những trang đó thường là một ý tưởng tồi. Bạn không nên cố gắng đưa nhạc phim vào mọi trang web. Thật tồi tệ. :)

âm thanh html5 sẽ phát nếu nó được bắt đầu do hành động của người dùng. Tải một trang không được tính. Vì vậy, bạn cần phải cấu trúc lại ứng dụng web của mình để trở thành một ứng dụng tất cả trong một trang. Thay vì liên kết mở một trang phát âm thanh, bạn cần liên kết đó để phát trên trang hiện tại mà không cần thay đổi trang. Quy tắc "tương tác người dùng" này áp dụng cho các phương thức html5 mà bạn có thể gọi trên phần tử âm thanh hoặc video. Các lệnh gọi trả về mà không có bất kỳ ảnh hưởng nào nếu chúng được kích hoạt tự động khi tải trang, nhưng chúng hoạt động khi được gọi từ trình xử lý sự kiện.


1

Giải pháp của tôi là kích hoạt từ một sự kiện chạm thực trong menu trước. Tất nhiên, họ không buộc bạn phải sử dụng một giao diện trình phát cụ thể. Đối với mục đích của tôi, điều này hoạt động tốt. Nếu bạn không có giao diện hiện có để sử dụng, thì có nghĩa là bạn đã sửa lỗi. Có lẽ bạn có thể thử các sự kiện nghiêng hoặc cái gì đó ...


1

Nếu bạn tạo phần tử Âm thanh bằng:

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

Và thêm suspendngười nghe sự kiện qua:

a.addEventListener("suspend", function () {console.log('suspended')}, false);

Và sau đó tải tệp vào Safari di động (iPad hoặc iPhone), bạn sẽ thấy 'bị treo' được đăng nhập vào bảng điều khiển dành cho nhà phát triển. Theo thông số kỹ thuật HTML5, điều này có nghĩa là, "Tác nhân người dùng hiện đang cố ý không tìm nạp dữ liệu phương tiện, nhưng không tải xuống toàn bộ tài nguyên phương tiện."

Gọi a.load () tiếp theo, kiểm tra sự kiện "canplay" và sau đó sử dụng a.play () có vẻ như là một phương pháp phù hợp để tự động kích hoạt âm thanh.


Tôi đã thử điều này nhưng nó có vẻ không hoạt động. Bất kỳ bản cập nhật? sandbox.coolaj86.info/html5-audio-tag-ios4.html
coolaj86

0

Hoạt động với jQuery, được thử nghiệm trên Ipad v.5.1.1

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

Bạn phải nối / xóa phần tử video khỏi trang.


3
Không hoạt động trên iPad 1 iOS 5.1.1 ... mặc dù hoạt động trên iPod 6.0 và iPhone
morgan_il

0

Tôi đã xử lý vấn đề này bằng cách đính kèm một trình xử lý sự kiện cho tất cả các sự kiện mà bạn được phép kích hoạt âm thanh vào phần tử body sẽ kích hoạt bất kỳ phần tử âm thanh html nào có tính năng tự động phát để phát một lần.

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

0

Điều này dường như hoạt động:

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

Xem nó hoạt động tại đây: http://www.johncoles.co.uk/ipad/test/1.html (Đã lưu trữ)

Kể từ iOS 4.2, điều này không còn hoạt động nữa. Lấy làm tiếc.


@ NisseEngström Có vẻ như đối với tôi rằng tệp mp3 cũng không được lưu trữ, vì vậy việc chỉnh sửa liên kết lưu trữ này khá tranh cãi.
Tạm biệt StackExchange

@FrankerZ: Có một liên kết mp3? Tôi đã bỏ lỡ nó. Cảm ơn.
Nisse Engström
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.