ฟังก์ชั่นหยุดเสียง HTML5


147

ฉันกำลังเล่นคลิปเสียงขนาดเล็กเมื่อคลิกแต่ละลิงก์ในการนำทาง

รหัส 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>

รหัส JS:

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

มันใช้งานได้ดีจนถึงตอนนี้

ปัญหาคือเมื่อคลิปเสียงทำงานแล้วและฉันคลิกที่ลิงค์ใด ๆ ไม่มีอะไรเกิดขึ้น

ฉันพยายามหยุดเสียงที่กำลังเล่นอยู่เมื่อคลิกที่ลิงก์ แต่ไม่มีเหตุการณ์โดยตรงสำหรับสิ่งนั้นใน Audio API ของ HTML5

ฉันลองใช้รหัสต่อไปนี้ แต่มันไม่ทำงาน

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

ข้อเสนอแนะโปรด?

คำตอบ:


350

แทนที่จะstop()ลองใช้:

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

สิ่งนี้ควรมีผลตามที่ต้องการ


6
สิ่งนี้ไม่ทำงานใน Chrome องค์ประกอบเสียงยังคงโหลดเสียงซึ่งไม่ใช่สิ่งที่จะเกิดขึ้น
Pieter

3
ใน Chrome การ<audio>โหลดยังคงมีpreloadคุณสมบัติบังคับnoneและ<source>src ถูกตัดออก
Pioneer Skies

6
งานนี้ขอบคุณ ในหมายเหตุด้านฉันอยากรู้ว่าทำไม w3c ตัดสินใจที่จะไม่รวมวิธีการหยุดในสเป็ค
Reahreic

25

ก่อนอื่นคุณต้องตั้งรหัสสำหรับองค์ประกอบเสียงของคุณ

ใน js ของคุณ:

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

var oldSrc = ply.src;// เพื่อระลึกถึงแหล่งเก่า

ply.src = "";// เพื่อหยุดผู้เล่นคุณต้องเปลี่ยนแหล่งที่มาด้วยไม่มีอะไร


4
ทางออกที่ดีที่สุดสำหรับการสตรีมเสียง
Hossein

1
ดี .. ที่จะทำการร้องขอเครือข่ายอื่นสำหรับไฟล์แหล่งกำเนิดเสียง
Md. Arafat Al Mahmud

เสียงจะไม่เล่นจนกว่าจะโหลดและสิ่งนี้จะทำให้เกิดความล่าช้าที่ไม่พึงประสงค์ในการเล่นเสียง
Abhi

ทางออกที่ดีของปัญหาเมื่อเล่นสตรีมเช่นวิทยุอินเทอร์เน็ตและ Firefox ซ้ำ ๆ อันสุดท้ายเมื่อหยุด / เล่นสลับ ขอบคุณมาก.
namikiri

14

นี่คือวิธีของฉันในการหยุด () วิธี:

ที่ไหนสักแห่งในรหัส:

audioCh1: document.createElement("audio");

แล้วหยุด ():

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

ด้วยวิธีนี้เราไม่ได้ผลิตคำขอเพิ่มเติมคำขอเก่าถูกยกเลิกและองค์ประกอบเสียงของเราอยู่ในสภาพที่สะอาด (ทดสอบใน Chrome และ FF):>


10

ฉันมีปัญหาเดียวกัน การหยุดควรหยุดการสตรีมและการเล่นออนไลน์จะใช้งานได้หากเป็นวิทยุ โซลูชันทั้งหมดที่ฉันเห็นมีข้อเสีย :

  • player.currentTime = 0 ดาวน์โหลดสตรีมต่อไป
  • player.src = ''เพิ่มerrorเหตุการณ์

ทางออกของฉัน:

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

และ HTML

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

ใช้งานได้ใน Chrome และ Firefox อย่างไรก็ตามใน Firefox มันส่งผลให้เกิดข้อผิดพลาดต่อไปนี้ (ในคอนโซล) [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] ดูเหมือนว่าจะไม่มีผลกระทบในทางลบเมื่อโค้ดยังคงทำงานหลังจากนี้
BReddy

6

วิธีนี้ใช้ได้ผล:

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

แต่ถ้าคุณไม่ต้องการเขียนโค้ดสองบรรทัดนี้ทุกครั้งที่คุณหยุดเสียงคุณสามารถทำหนึ่งในสองอย่างนี้ได้ ครั้งที่สองที่ฉันคิดว่าเหมาะสมกว่าและฉันไม่แน่ใจว่าทำไม "เทพเจ้าแห่งมาตรฐานจาวาสคริปต์" จึงไม่ได้สร้างมาตรฐานนี้

วิธีแรก: สร้างฟังก์ชั่นและส่งเสียง

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

//then using it:
stopAudio(audio);

วิธีที่สอง (โปรดปราน): ขยายคลาสเสียง:

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

ฉันมีสิ่งนี้ในไฟล์จาวาสคริปต์ที่ฉันเรียกว่า "AudioPlus.js" ซึ่งฉันใส่ไว้ใน html ของฉันก่อนที่สคริปต์ใด ๆ ที่จะจัดการกับเสียง

จากนั้นคุณสามารถเรียกใช้ฟังก์ชันหยุดบนวัตถุเสียง:

audio.stop();

ปัญหาโครเมี่ยมในที่สุดด้วย "canplaythrough":

ฉันไม่ได้ทดสอบสิ่งนี้ในเบราว์เซอร์ทั้งหมด แต่นี่เป็นปัญหาที่ฉันเจอใน Chrome หากคุณพยายามตั้งค่า currentTime บนเสียงที่มีฟังเหตุการณ์ "canplaythrough" แนบอยู่คุณจะทริกเกอร์เหตุการณ์นั้นอีกครั้งซึ่งอาจนำไปสู่ผลลัพธ์ที่ไม่พึงประสงค์

ดังนั้นวิธีการแก้ไขคล้ายกับกรณีทั้งหมดเมื่อคุณแนบ listener เหตุการณ์ที่คุณต้องการให้แน่ใจว่าไม่ได้ถูกทริกเกอร์อีกครั้งคือการลบ listener เหตุการณ์หลังจากการเรียกครั้งแรก บางสิ่งเช่นนี้

//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 ...
});

โบนัส:

โปรดทราบว่าคุณสามารถเพิ่มวิธีการที่กำหนดเองได้มากขึ้นในคลาส Audio (หรือคลาส Javascript ดั้งเดิมใด ๆ สำหรับเรื่องนั้น)

ตัวอย่างเช่นหากคุณต้องการวิธี "เริ่มใหม่" ที่เริ่มเสียงใหม่มันอาจมีลักษณะดังนี้:

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

function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } การทำสิ่งนี้สิ้นสุดลงสำหรับฉันและลบไอคอนลำโพงในเบราว์เซอร์ Chrome ที่ปรากฏขึ้นเมื่อเล่นเสียงบนหน้า ทดสอบกับ Chrome เวอร์ชัน 59.0.3071.109
lasec0203

โดยทั่วไปฉันไม่แนะนำให้ขยายต้นแบบเช่นนี้ แอปพลิเคชั่นเสียงหนักอาจมีฟังก์ชั่นหยุดที่แตกต่างกันสำหรับกรณีที่แตกต่างกันและ messing กับต้นแบบมีแนวโน้มที่จะนำไปสู่ข้อบกพร่องในระยะยาว imho
milearon

5

จากฟังก์ชั่นจาวาสคริปต์ของฉันเองเพื่อสลับเล่น / หยุดชั่วคราว - เนื่องจากฉันจัดการกระแสข้อมูลวิทยุฉันต้องการให้ล้างบัฟเฟอร์เพื่อให้ผู้ฟังไม่จบการซิงค์กับสถานีวิทยุ

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

ปรากฎว่าเพียงแค่ล้างค่าเวลาปัจจุบันไม่ได้ตัดภายใต้ Chrome จำเป็นต้องล้างแหล่งที่มาด้วยและโหลดกลับมาหวังว่านี่จะช่วยได้


4

ในฐานะที่เป็นบันทึกด้านข้างและเนื่องจากเมื่อเร็ว ๆ นี้ฉันใช้วิธีการหยุดที่ให้ไว้ในคำตอบที่ได้รับการยอมรับตามลิงค์นี้:

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

โดยการตั้งค่า currentTime ด้วยตนเองอาจทำให้เหตุการณ์ 'canplaythrough' บนองค์ประกอบเสียง ในลิงค์มันกล่าวถึง Firefox แต่ฉันพบเหตุการณ์นี้เกิดขึ้นหลังจากตั้งค่า currentTime ด้วยตนเองบน Chrome ดังนั้นหากคุณมีพฤติกรรมที่แนบมากับเหตุการณ์นี้คุณอาจจบลงด้วยการวนรอบเสียง


3

บางครั้งมันไม่ทำงานในโครเมียม

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

แค่เปลี่ยนแบบนั้น

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

2

shamangeorge wrote:

โดยการตั้งค่า currentTime ด้วยตนเองอาจทำให้เหตุการณ์ 'canplaythrough' บนองค์ประกอบเสียง

นี่คือสิ่งที่จะเกิดขึ้นและการหยุดชั่วคราวจะทำให้ pauseเหตุการณ์ซึ่งทั้งสองอย่างนี้ทำให้เทคนิคนี้ไม่เหมาะสำหรับการใช้เป็นวิธี "หยุด" นอกจากนี้การตั้งค่าsrcตามที่แนะนำโดย zaki จะทำให้ลองเล่นที่จะโหลด URL หน้าปัจจุบันเป็นไฟล์มีเดีย (และล้มเหลว) ถ้าautoplayมีการเปิดใช้งาน - การตั้งค่าsrcที่จะnullไม่ได้รับอนุญาต; มันจะถูกถือว่าเป็น URL เสมอ ดูเหมือนว่าจะไม่มีวิธีที่ดีในการให้วิธีการ "หยุด" สั้น ๆ ดังนั้นฉันขอแนะนำเพียงแค่วางปุ่มหยุดเฉพาะและให้หยุดชั่วคราวและข้ามปุ่มย้อนกลับแทน - ปุ่มหยุดจะไม่เพิ่มฟังก์ชันใด ๆ .


1

วิธีการนี้คือ "กำลังดุร้าย" แต่ใช้งานได้โดยสมมติว่าใช้ jQuery คือ "อนุญาต" ล้อมรอบ<audio></audio>แท็ก"ผู้เล่น" ของคุณด้วย div (ที่นี่ด้วย id ของ "plHolder")

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

จากนั้นจาวาสคริปต์นี้จะทำงาน:

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

สิ่งเดียวกันนี้อธิบายโดยซากิในคำตอบของเขาด้านบนโดยไม่ใช้ jquery
Alok Jain

ฉันไม่ได้ทำการทดลอง แต่ฉันไม่แน่ใจว่าวิธีการของเขาจะใช้ได้ถ้ามีแท็ก <source> หลายแท็ก
user3062615

#FlHolderดูเหมือนจะเป็นคำผิดสำหรับ#plHolder
Pioneer Skies

1
ในการตอบกลับความคิดเห็น @ alok-jain: ฉันคิดว่าคำตอบนี้แตกต่างอย่างสิ้นเชิงจาก @zaki ที่นี่เราจะทำการเรนเดอร์องค์ประกอบใน DOM อีกครั้งในคำตอบอื่น ๆ เขาเพียงแค่ "blanking" srcคุณลักษณะของผู้เล่น
Pioneer Skies

0

ฉันเชื่อว่ามันเป็นการดีที่จะตรวจสอบว่าเสียงกำลังเล่นอยู่และรีเซ็ตคุณสมบัติ currentTime หรือไม่

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

0

สำหรับฉันรหัสที่ทำงานได้ดี (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">...

หวังว่าความช่วยเหลือนี้


0

สิ่งที่ฉันชอบทำคือลบตัวควบคุมออกอย่างสมบูรณ์โดยใช้ Angular2 จากนั้นจะโหลดใหม่เมื่อเพลงถัดไปมีเส้นทางเสียง:

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

จากนั้นเมื่อฉันต้องการยกเลิกการโหลดในรหัสฉันทำสิ่งนี้:

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

เมื่อกำหนดเพลงถัดไปตัวควบคุมจะถูกสร้างขึ้นใหม่ทั้งหมดตั้งแต่ต้น:

this.song = this.songOnDeck;

0

วิธีง่ายๆในการแก้ไขข้อผิดพลาดนี้คือการตรวจจับข้อผิดพลาด

audioElement.play () ส่งคืนสัญญาดังนั้นโค้ดต่อไปนี้ที่มี. catch () น่าจะเพียงพอสำหรับจัดการปัญหานี้:

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

หมายเหตุ: คุณอาจต้องการแทนที่ฟังก์ชั่นลูกศรด้วยฟังก์ชั่นที่ไม่ระบุชื่อเพื่อความเข้ากันได้แบบย้อนหลัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.