Chức năng dừng âm thanh HTML5


147

Tôi đang phát một đoạn âm thanh nhỏ khi nhấp vào từng liên kết trong điều hướng của mình

Mã HTML:

<audio tabindex="0" id="beep-one" controls preload="auto" >
    <source src="audio/Output 1-2.mp3">
    <source src="audio/Output 1-2.ogg">
</audio>

Mã JS:

$('#links a').click(function(e) {
    e.preventDefault();
    var beepOne = $("#beep-one")[0];
    beepOne.play();
});

Nó hoạt động tốt cho đến nay.

Vấn đề là khi một clip âm thanh đã chạy và tôi nhấp vào bất kỳ liên kết nào thì không có gì xảy ra.

Tôi đã cố gắng ngăn âm thanh đã phát khi nhấp vào liên kết, nhưng không có sự kiện trực tiếp nào cho điều đó trong API âm thanh của HTML5

Tôi đã thử làm theo mã nhưng nó không hoạt động

$.each($('audio'), function () {
    $(this).stop();
});

Có gợi ý nào không?

Câu trả lời:


350

Thay vì stop()bạn có thể thử với:

sound.pause();
sound.currentTime = 0;

Điều này sẽ có hiệu quả mong muốn.


6
Điều này không hoạt động trong Chrome. Phần tử âm thanh tiếp tục tải âm thanh, đó không phải là điều nên xảy ra.
Pieter

3
Trong Chrome, việc <audio>tiếp tục tải cũng với preloadthuộc tính bắt buộc none<source>src bị loại bỏ.
Bầu trời tiên phong

6
Điều này làm việc, cảm ơn. Bên cạnh đó, tôi rất muốn biết lý do tại sao w3c quyết định không bao gồm phương thức dừng trong thông số kỹ thuật.
Reahreic

25

trước tiên, bạn phải đặt id cho thành phần âm thanh của mình

trong js của bạn:

var ply = document.getElementById('player');

var oldSrc = ply.src;// chỉ để nhớ nguồn cũ

ply.src = "";// để dừng trình phát, bạn phải thay thế nguồn không có gì


4
Giải pháp tốt nhất để truyền phát âm thanh
Hossein

1
tốt..thì sẽ thực hiện một yêu cầu mạng khác cho tệp nguồn âm thanh
Md. Arafat Al Mahmud

Âm thanh sẽ không phát cho đến khi được tải và điều này sẽ gây ra sự chậm trễ không mong muốn khi phát âm thanh.
Abhi

Một giải pháp tốt cho vấn đề khi phát một luồng như radio internet và Firefox lặp lại đoạn cuối cùng khi tạm dừng / phát được bật. Cảm ơn bạn rất nhiều.
namikiri

14

Đây là cách làm phương thức stop () của tôi:

Một nơi nào đó trong mã:

audioCh1: document.createElement("audio");

và sau đó dừng lại ():

this.audioCh1.pause()
this.audioCh1.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=';

Theo cách này, chúng tôi không tạo ra yêu cầu bổ sung, yêu cầu cũ bị hủy và thành phần âm thanh của chúng tôi ở trạng thái sạch (được thử nghiệm trong Chrome và FF):>


9

Tôi đã có vấn đề tương tự. Một điểm dừng nên dừng luồng và phát trực tiếp nếu nó là một đài phát thanh. Tất cả các giải pháp tôi thấy có một nhược điểm :

  • player.currentTime = 0 tiếp tục tải xuống luồng.
  • player.src = ''nâng cao errorsự kiện

Giải pháp của tôi:

var player = document.getElementById('radio');
player.pause();
player.src = player.src;

Và HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>

Điều này hoạt động trong Chrome và Firefox. Tuy nhiên, trong Firefox, nó dẫn đến lỗi sau (trong bảng điều khiển) [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] Nó dường như không có tác động tiêu cực khi mã tiếp tục thực thi sau đó (không giống như Ngoại lệ chưa được phát hiện).
BReddy

6

Phương pháp này hoạt động:

audio.pause();
audio.currentTime = 0;

Nhưng nếu bạn không muốn phải viết hai dòng mã này mỗi khi bạn dừng âm thanh, bạn có thể thực hiện một trong hai điều sau. Thứ hai tôi nghĩ là phù hợp hơn và tôi không chắc tại sao "các vị thần của các tiêu chuẩn javascript" không tạo ra tiêu chuẩn này.

Phương pháp đầu tiên: tạo một chức năng và truyền âm thanh

function stopAudio(audio) {
    audio.pause();
    audio.currentTime = 0;
}

//then using it:
stopAudio(audio);

Phương thức thứ hai (được ưa thích): mở rộng lớp Audio:

Audio.prototype.stop = function() {
    this.pause();
    this.currentTime = 0;
};

Tôi có cái này trong một tệp javascript mà tôi gọi là "AudioPlus.js" mà tôi đưa vào html của mình trước bất kỳ tập lệnh nào sẽ xử lý âm thanh.

Sau đó, bạn có thể gọi chức năng dừng trên các đối tượng âm thanh:

audio.stop();

CUỐI CÙNG CHROME CUỐI CÙNG VỚI "canplayENC":

Tôi chưa thử nghiệm điều này trong tất cả các trình duyệt nhưng đây là sự cố tôi gặp phải trong Chrome. Nếu bạn cố gắng đặt currentTime trên một âm thanh có trình nghe sự kiện "có thể phát" được đính kèm với nó thì bạn sẽ kích hoạt lại sự kiện đó có thể dẫn đến kết quả không mong muốn.

Vì vậy, giải pháp, tương tự như tất cả các trường hợp khi bạn đã đính kèm một trình lắng nghe sự kiện mà bạn thực sự muốn đảm bảo rằng nó không được kích hoạt lại, là loại bỏ trình nghe sự kiện sau cuộc gọi đầu tiên. Một cái gì đó như thế này:

//note using jquery to attach the event. You can use plain javascript as well of course.
$(audio).on("canplaythrough", function() {
    $(this).off("canplaythrough");

    // rest of the code ...
});

TẶNG KEM:

Lưu ý rằng bạn có thể thêm các phương thức tùy chỉnh hơn nữa vào lớp Audio (hoặc bất kỳ lớp javascript gốc nào cho vấn đề đó).

Ví dụ: nếu bạn muốn một phương thức "khởi động lại" để khởi động lại âm thanh, nó có thể trông giống như:

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};

function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } Việc này đã kết thúc với tôi và xóa biểu tượng loa trong Trình duyệt Chrome xuất hiện khi âm thanh đang phát trên trang. đã thử nghiệm trên Chrome Phiên bản 59.0.3071.109
lasec0203

Nói chung, tôi không khuyên bạn nên mở rộng các nguyên mẫu như thế này. Đơn nghe nặng có thể có chức năng dừng khác nhau đối với trường hợp khác nhau và rối tung với nguyên mẫu là khả năng dẫn đến lỗi trong dài hạn IMHO
milesaron

5

Từ chức năng javascript của riêng tôi để chuyển đổi Phát / Tạm dừng - vì tôi đang xử lý một luồng radio, tôi muốn nó xóa bộ đệm để người nghe không bị đồng bộ hóa với đài phát thanh.

function playStream() {

        var player = document.getElementById('player');

        (player.paused == true) ? toggle(0) : toggle(1);

}

function toggle(state) {

        var player = document.getElementById('player');
        var link = document.getElementById('radio-link');
        var src = "http://192.81.248.91:8159/;";

        switch(state) {
                case 0:
                        player.src = src;
                        player.load();
                        player.play();
                        link.innerHTML = 'Pause';
                        player_state = 1;
                        break;
                case 1:
                        player.pause();
                        player.currentTime = 0;
                        player.src = '';
                        link.innerHTML = 'Play';
                        player_state = 0;
                        break;
        }
}

Hóa ra, chỉ cần xóa currentTime không cắt nó trong Chrome, cũng cần phải xóa nguồn và tải lại. Hy vọng điều này sẽ giúp.


4

Như một lưu ý phụ và bởi vì gần đây tôi đã sử dụng phương pháp dừng được cung cấp trong câu trả lời được chấp nhận, theo liên kết này:

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events

bằng cách đặt currentTime theo cách thủ công, người ta có thể kích hoạt sự kiện 'canplayENC' trên thành phần âm thanh. Trong liên kết, nó có đề cập đến Firefox, nhưng tôi đã gặp phải sự kiện này sau khi cài đặt currentTime theo cách thủ công trên Chrome. Vì vậy, nếu bạn có hành vi gắn liền với sự kiện này, bạn có thể kết thúc trong một vòng lặp âm thanh.


3

Nó không hoạt động đôi khi trong chrome,

sound.pause();
sound.currentTime = 0;

chỉ cần thay đổi như vậy

sound.currentTime = 0;
sound.pause();

2

shamangeorge đã viết:

bằng cách đặt currentTime theo cách thủ công, người ta có thể kích hoạt sự kiện 'canplayENC' trên thành phần âm thanh.

Đây thực sự là những gì sẽ xảy ra, và tạm dừng cũng sẽ kích hoạt pausesự kiện, cả hai điều này làm cho kỹ thuật này không phù hợp để sử dụng làm phương pháp "dừng". Hơn nữa, thiết lập srctheo đề nghị của Zaki sẽ làm cho người chơi cố gắng để tải URL của trang hiện tại như một tập tin phương tiện truyền thông (và thất bại) nếu autoplayđược kích hoạt - thiết lập srcđể nullkhông được phép; nó sẽ luôn được coi là một URL. Việc tiêu diệt đối tượng người chơi dường như không có cách nào tốt để cung cấp phương thức "dừng", vì vậy tôi khuyên bạn chỉ nên bỏ nút dừng chuyên dụng và cung cấp tạm dừng và bỏ qua các nút quay lại - thay vào đó, nút dừng sẽ không thực sự bổ sung bất kỳ chức năng nào .


1

Cách tiếp cận này là "sức mạnh vũ phu", nhưng nó hoạt động với giả định sử dụng jQuery là "được phép". Bao quanh <audio></audio>các thẻ "trình phát" của bạn bằng một div (ở đây có id là "plHolder").

<div id="plHolder">
     <audio controls id="player">
     ...
     </audio>
<div>

Sau đó, javascript này sẽ hoạt động:

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}

Điều tương tự được giải thích bởi zaki trong câu trả lời của anh ta ở trên, mà không sử dụng jquery.
Alok Jain

Tôi đã không thử nghiệm với nó, nhưng tôi không chắc rằng phương pháp của anh ấy sẽ hoạt động nếu có nhiều thẻ <source>.
3062615

#FlHoldercó vẻ như là một lỗi đánh máy cho#plHolder
Pioneer Skies

1
Trả lời bình luận của @ alok-jain: Tôi nghĩ câu trả lời này hoàn toàn khác với câu trả lời của @zaki. Ở đây chúng tôi đang kết xuất lại một phần tử trong DOM, trong câu trả lời khác, anh ta chỉ "làm trống" srcthuộc tính của trình phát.
Bầu trời tiên phong

0

Tôi tin rằng sẽ tốt nếu kiểm tra xem âm thanh có đang phát và đặt lại thuộc tính currentTime không.

if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
    sound.currentTime = 0;
}
sound.play();

0

Đối với tôi mã đó làm việc tốt. (IE10 +)

var Wmp = document.getElementById("MediaPlayer");                
    Wmp.controls.stop();

<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6"
    standby="Loading áudio..." style="width: 100%; height: 170px" id="MediaPlayer">...

Hy vọng điều này giúp đỡ.


0

Những gì tôi muốn làm là loại bỏ hoàn toàn điều khiển bằng Angular2, sau đó nó được tải lại khi bài hát tiếp theo có đường dẫn âm thanh:

<audio id="audioplayer" *ngIf="song?.audio_path">

Sau đó, khi tôi muốn dỡ nó trong mã, tôi làm điều này:

this.song = Object.assign({},this.song,{audio_path: null});

Khi bài hát tiếp theo được chỉ định, điều khiển sẽ được tạo lại hoàn toàn từ đầu:

this.song = this.songOnDeck;

0

Cách đơn giản để khắc phục lỗi này là bắt lỗi.

audioEuity.play () trả về một lời hứa, vì vậy đoạn mã sau với .catch () sẽ đủ để quản lý vấn đề này:

function playSound(sound) {
  sfx.pause();
  sfx.currentTime = 0;
  sfx.src = sound;
  sfx.play().catch(e => e);
}

Lưu ý: Bạn có thể muốn thay thế chức năng mũi tên bằng chức năng ẩn danh để tương thích ngược.

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.