【问题标题】:Continuous Html5 audio .play() with only 1st time trigger仅第一次触发的连续 Html5 音频 .play()
【发布时间】:2013-02-19 04:29:32
【问题描述】:

我想通过在每个函数中使用.play() 执行函数调用后备来播放连续的声音序列,以逐个播放声音。

最有趣的是: 每次在我的 iPad 设备上播放都会有不同的声音表现。 *有时播放音频 3 次,有时播放 4 次,甚至只播放 1 次!*

只有 iPad 上的“突然停止问题”,在我的谷歌浏览器上没问题。

这不是 iPad 的自动播放问题,因为我已经第一次触发了...

请看一下并在 iPad 上进行测试,请帮助...

HTML - 正文:

<audio id="html5soundtag"> 
    <source src="1.mp3" type="audio/mpeg">
</audio> 
<a href="javascript://" onClick="playhtml5sound1('1.mp3')">aaaa</a> 

Javascript:

var audioPath ="";

var audioElement = document.getElementById('html5soundtag');

function playhtml5sound1(filename){ 
    audioPath = filename;
    audioElement.src = audioPath;
    audioElement.src = audioPath
    audioElement.load()
    audioElement.play();
    audioElement.addEventListener("ended",soundcallback1);
};
var soundcallback1 = function (){
    alert("1st");
    audioElement.removeEventListener("ended",soundcallback1);
    playhtml5sound2("1.mp3");
}


function playhtml5sound2(filename){
    audioPath = filename;
    audioElement.src = audioPath;
    audioElement.src = audioPath
    audioElement.load();        
    audioElement.play();
    audioElement.addEventListener("ended",soundcallback2);

};
var soundcallback2 = function (){
    alert("2nd");
    audioElement.removeEventListener("ended",soundcallback2);
    playhtml5sound3("1.mp3");
}

function playhtml5sound3(filename){
    audioPath = filename;
    audioElement.src = audioPath;
    audioElement.src = audioPath
    audioElement.load();
    audioElement.play();
    audioElement.addEventListener("ended",soundcallback3);

};var soundcallback3 = function (){
    alert("3rd");
    audioElement.removeEventListener("ended",soundcallback3);
    playhtml5sound4("1.mp3");
}

function playhtml5sound4(filename){
    audioPath = filename;
    audioElement.src = audioPath;
    audioElement.src = audioPath
    audioElement.load();
    audioElement.play();

    audioElement.addEventListener("ended",soundcallback4);

};var soundcallback4 = function (){
    alert("4th");
    audioElement.removeEventListener("ended",soundcallback4);
    playhtml5sound5("1.mp3");
}

function playhtml5sound5(filename){
    audioPath = filename;
    audioElement.src = audioPath;
    audioElement.src = audioPath
    audioElement.load();
    audioElement.play();

    audioElement.addEventListener("ended",soundcallback5);

};var soundcallback5 = function (){
    alert("5th");
    audioElement.removeEventListener("ended",soundcallback5);
    playhtml5sound6("1.mp3");
}

function playhtml5sound6(filename){
    alert("This is End. " + filename);
}

【问题讨论】:

  • 你只使用 1.mp3 吗?有 6 个不同的回调?你打算播放 1.mp3、2.mp3 等吗?
  • 是的,对于测试我只使用单个样本声音“1.mp3”,因为现在我的问题是在 ipad 上运行时回调会突然停止(停止)......并且每次都不同在“死”的时候!比如只有2个回调运行,下一次完全运行,下一次只运行1个回调...只是刷新网页后不同...
  • 拜托,DRY 绝对不需要 5 个几乎相同的函数,更不用说事件监听器的杂耍了。
  • 您的 iPad 是哪一代以及您运行的是哪个 iOS?
  • Sorry Cerbrus:真的是因为每次回调都会随机停止所以我添加了它们进行测试,抱歉代码长...

标签: javascript jquery html ipad html5-audio


【解决方案1】:

这应该可以解决您的问题,并且至少可以让您的代码更易于维护:

var audioPath = "";
var audioElement = document.getElementById('html5soundtag');

var soundIndex = 0;
var sounds = ["1.mp3","2.mp3","3.mp3","4.mp3","5.mp3"]

function playhtml5sound(){
    if(soundIndex < sounds.length){
        audioPath = sounds[soundIndex];
        audioElement.src = audioPath;
        audioElement.load()
        audioElement.play();
        soundIndex++;
    }else{
        audioElement.removeEventListener("ended",playhtml5sound);
        alert("Last sound ended!")
    }
};

audioElement.addEventListener("ended", playhtml5sound);
<a href="javascript://" onClick="playhtml5sound()">aaaa</a> 

每次音乐结束时,都会执行playhtml5sound(),播放下一个声音。
如果播放了最后一个声音,则移除事件监听器,并提醒结束。

【讨论】:

    【解决方案2】:

    不是直接的答案,但代码太大,无法在评论中显示。

    我建议您将以下代码添加到您的脚本中,并检查控制台日志中是否存在未结束的任何其他事件(例如停滞或错误事件)。我在 iPad 和 iPod 上测试过,都可以,可能是网络问题。

    var media_events = new Array();
    function audioattachevents(selector) {
        media_events["abort"] = 0;
        media_events["error"] = 0;
        media_events["mousewheel"] = 0;
        media_events["blur"] = 0;
        media_events["focus"] = 0;
        media_events["pause"] = 0;
        media_events["canplay"] = 0;
        media_events["formchange"] = 0;
        media_events["play"] = 0;
        media_events["canplaythrough"] = 0;
        media_events["forminput"] = 0;
        media_events["playing"] = 0;
        media_events["change"] = 0;
        media_events["input"] = 0;
        media_events["progress"] = 0;
        media_events["click"] = 0;
        media_events["invalid"] = 0;
        media_events["ratechange"] = 0;
        media_events["contextmenu"] = 0;
        media_events["keydown"] = 0;
        media_events["readystatechange"] = 0;
        media_events["dblclick"] = 0;
        media_events["keypress"] = 0;
        media_events["scroll"] = 0;
        media_events["drag"] = 0;
        media_events["keyup"] = 0;
        media_events["seeked"] = 0;
        media_events["dragend"] = 0;
        media_events["load*"] = 0;
        media_events["seeking"] = 0;
        media_events["dragenter"] = 0;
        media_events["loadeddata"] = 0;
        media_events["select"] = 0;
        media_events["dragleave"] = 0;
        media_events["loadedmetadata"] = 0;
        media_events["show"] = 0;
        media_events["dragover"] = 0;
        media_events["loadstart"] = 0;
        media_events["stalled"] = 0;
        media_events["dragstart"] = 0;
        media_events["mousedown"] = 0;
        media_events["submit"] = 0;
        media_events["drop"] = 0;
        media_events["mousemove"] = 0;
        media_events["suspend"] = 0;
        media_events["durationchange"] = 0;
        media_events["mouseout"] = 0;
        media_events["timeupdate"] = 0;
        media_events["emptied"] = 0;
        media_events["mouseover"] = 0;
        media_events["volumechange"] = 0;
        media_events["ended"] = 0;
        media_events["mouseup"] = 0;
        media_events["waiting"] = 0;
    
        for (key in media_events) {
          selector.bind(key, function (e, data) {
            console.log(e.type);
          });
        }
    }
    
    audioattachevents($('#html5soundtag'));
    

    特别是对于那些想要简写法的人:

    media_events = {"abort":0,"error":0, "mousewheel":0, "blur":0, "focus":0, "pause":0, 
       "canplay":0, "formchange":0, "play":0, "canplaythrough":0, "forminput":0, 
       "playing":0, "change":0, "input":0, "progress":0, "click":0, "invalid":0, 
       "ratechange":0, "contextmenu":0, "keydown":0, "readystatechange":0,       
       "dblclick":0, "keypress":0, "scroll":0, "drag":0, "keyup":0, "seeked":0, 
       "dragend":0, "load*":0, "seeking":0, "dragenter":0, "loadeddata":0, 
       "select":0, "dragleave":0, "loadedmetadata":0, "show":0, "dragover":0, 
       "loadstart":0, "stalled":0, "dragstart":0, "mousedown":0, "submit":0, 
       "drop":0, "mousemove":0, "suspend":0, "durationchange":0, 
       "mouseout":0, "timeupdate":0, "emptied":0, "mouseover":0, 
       "volumechange":0, "ended":0, "mouseup":0, "waiting":0}
    

    【讨论】:

    • 谢谢巴特,我现在就试试这个!顺便说一句,您的意思是您可以显示“This is End”的警报。每次都一样?
    • 如果您需要存储大量字符串,请使用数组。或者如果你必须使用一个对象,至少使用短符号:media_events = {"abort":0, "error":0, etc...}。实际上,您正在将对象初始化为 var media_events = new Array(); 这不起作用。您不能设置数组的key / value 属性。你的数组是空的。
    • @Cerbrus 同意,但是我需要更改现有代码,所以我只使用复制和粘贴。对于 user1900121:以上内容仅用于测试您是否收到任何其他可能为您提供音频中止原因的事件。例如,如果网络停止、重新传输以及 iPad 中的 WiFi 很糟糕(这可能会发生)
    • “更改现有代码”?将您的非工作对象表示法转换为适当的数组需要 2 分钟的工作时间。
    • @Cerbrus:不工作?你测试了吗?我猜你是那个反对的人。是的,我确实需要 OBJECT,因为在我的代码中我还使用了一些东西来计算事件的数量!
    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 2018-09-27
    • 2020-10-08
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多