【问题标题】:HTML5 Audio: How to Play only a Selected Portion of an Audio File (audio sprite)?HTML5 音频:如何仅播放音频文件(音频精灵)的选定部分?
【发布时间】:2020-10-04 20:11:23
【问题描述】:

我正在开发一个 iOS 节拍器网络应用。由于移动版 Safari 只能播放 one sound at a time,因此我正在尝试创建一个“音频精灵”——我可以在其中使用单个音轨的不同片段来生成不同的声音。我有一个 1 秒的剪辑,上面有 2 个半秒的声音。

<audio id="sample" src="sounds.mp3"></audio>

<a href="javascript:play1();">Play1</a>
<a href="javascript:play2();">Play2</a>
<a href="javascript:pauseAudio();">Pause</a>

<script>
var audio = document.getElementById('click');

function play1(){
    audio.currentTime = 0;
    audio.play();

    // This is the problem area
    audio.addEventListener('timeupdate', function (){
        if (currentTime >= 0.5) {
            audio.pause();
        }
    }, false);
}   

function play2(){
    audio.currentTime = 0.5;
    audio.play();
}

function pause(){
    audio.pause();
}
</script>

JSFiddle 上查看。

如您所见,我尝试使用 'timeupdate' 事件 (jPlayer example) 无济于事。

我见过 Remy Sharp's post on audio sprites,但是 (A) 我无法让它为我工作,并且 (B) 我宁愿远离库依赖项。

有什么想法吗?


更新

我现在可以使用 setInterval:

function play1(){
    audio.currentTime = 0;
    audio.play();
    int = setInterval(function() {
        if (audio.currentTime > 0.4) {
            audio.pause();
            clearInterval(int);
        }
    }, 10);
}    

function play2(){
    clearInterval(int);
    audio.currentTime = 0.5;
    audio.play();
}

序列和设置/清除间隔存在一些问题,但出于我的目的 - 它似乎有效。

JSFiddle

附:如果有人对此有修复,可以在游戏和界面音效中使用。

【问题讨论】:

标签: javascript html dom-events mobile-safari html5-audio


【解决方案1】:

我认为这里有几个问题。

首先,每次用户点击 Play 1 时,您都会添加一个事件监听器。

我也觉得

if (currentTime >= 0.5) { ...

应该是

if (audio.currentTime >= 0.5) { ...

这也有效:

<audio id="sample" src="http://dl.dropbox.com/u/222645/click1sec.mp3" controls preload></audio>

<a href="javascript:playSegment(0.0, 0.5);">Play1</a>
<a href="javascript:playSegment(0.5);">Play2</a>

<script>
var audio = document.getElementById('sample');
var segmentEnd;

audio.addEventListener('timeupdate', function (){
    if (segmentEnd && audio.currentTime >= segmentEnd) {
        audio.pause();
    }   
    console.log(audio.currentTime);
}, false);

function playSegment(startTime, endTime){
    segmentEnd = endTime;
    audio.currentTime = startTime;
    audio.play();
}
</script>

【讨论】:

  • 这是一个很好的解决方案,展示了良好的功能。但是,请不要,间隔可能应该是整秒的数量级。在 Chrome 中测试它,我发现浏览器经常会超过 0.4 秒而没有道歉。
  • @Sam Dutton 我尝试使用我自己的保管箱链接,但由于某种原因它没有播放。它是一个 .mp3 文件
【解决方案2】:

我没有找到一个干净的函数来播放音频对象的片段,所以这就是我想出的。也解决了用户在短时间内点击多个触发器会出现的以下错误。

“未捕获(承诺中)DOMException:play() 请求被对 pause() 的调用中断”

const audioObj_1 = new Audio('/some_audio_file.m4a');
playSegment(audioObj_1 , 1.11, 2.45); // this will play from 1.11 sec to 2.45 sec

function playSegment(audioObj, start, stop){
    let audioObjNew = audioObj.cloneNode(true); //this is to prevent "play() request was interrupted" error. 
    audioObjNew.currentTime = start;
    audioObjNew.play();
    audioObjNew.int = setInterval(function() {
        if (audioObjNew.currentTime > stop) {
            audioObjNew.pause();
            clearInterval(audioObjNew.int);
        }
    }, 10);
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2014-11-16
    • 2013-08-03
    • 1970-01-01
    • 2017-04-12
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多