播放html5中的音频范围

问题描述 投票:4回答:2

我希望能够有一些按钮,这些按钮可以播放较大文件中的某些音频范围。类似于:

<button onclick="playClip('http://blah/source1.mp3', 2.5, 3.0, 1.0)">Play clip 1</button>
<button onclick="playClip('http://blah/source2.mp3', 10.0, 2.0, 0.5)">Play clip 2 slow</button>

其中playClip具有这样的模式:

function playClip(src, startOffset, length, rate) {
  // What to put here?
}

或者不是长度,而是结束偏移量。

有人可以指出我可以执行此操作的代码,还是可以帮助我编写代码?我能找到的最接近的是https://gist.github.com/remy/753003/download#,但是我需要不同大小的剪辑,可能来自不同的文件,并且指定了播放速率。恐怕我对Javascript的经验有限。

我正在尝试替换执行此操作的Silverlight应用程序。

谢谢。

-约翰

html5 audio html5-audio
2个回答
6
投票

都使用Media Fragments URI语法:

var src,
    startOffset,
    endOffset,
    playbackRate,
    audio = new Audio(src + '#t=' + startOffset + ',' + endOffset);

audio.onloadedmetadata = function() {
  audio.playbackRate = playbackRate;
  audio.play();
};

timeupdate事件:

var audio = new Audio( ... ),
    startOffset,
    endOffset,
    playbackRate;

audio.onloadedmetadata = function() {
  audio.playbackRate = playbackRate;
  audio.currentTime = startOffset;
  audio.play();
};

audio.ontimeupdate = function() {
  if (audio.currentTime >= endOffset) {
    audio.pause();
  }
};

参考:


1
投票

这里是我当前代码的摘录,它同时使用音频控件的事件和超时来确保音频停止。有可能需要修剪的音量滑块参考。

var jt_audioControl;
var jt_audioSource;
var jt_audioFiles;
var jt_audioFileIndex;
var jt_audioFile;
var jt_audioStartTime;
var jt_audioEndTime;
var jt_audioPlaybackRate;
var jt_audioTimeoutHandle;
var jt_audioLink;
var jt_audioMimeType;
var jt_audioMediaType;
var jt_volumeSlider;

function jt_onAudioTimeUpdate() {
    if (jt_audioEndTime > 0.0) {
        if (jt_audioControl.currentTime >= jt_audioEndTime) {
            //alert('stopped: jt_audioControl.currentTime = ' + jt_audioControl.currentTime + ' jt_audioEndTime = ' + jt_audioEndTime);
            jt_audioControl.pause();
            //jt_audioStartTime = jt_audioEndTime = 0.0;
        }
    }
}

function jt_onAudioCanPlay() {
    jt_audioControl.pause();
    jt_audioControl.currentTime = jt_audioStartTime;
    jt_audioControl.defaultPlaybackRate = jt_audioPlaybackRate;
    jt_audioControl.playbackRate = jt_audioPlaybackRate;
    jt_audioControl.play();
    jt_audioControl.currentTime = jt_audioStartTime;
    jt_volumeSliderChanged();   // Set initial value to slider.
    var timeout = (((jt_audioEndTime - jt_audioStartTime)) / jt_audioPlaybackRate) * 1000;
    //alert('jt_audioEndTime = ' + jt_audioEndTime + ', timeout = ' + timeout);
    if (jt_audioEndTime > 0.0) {
        jt_audioTimeoutHandle = setTimeout(jt_onAudioEnded, timeout);
        //alert('jt_audioTimeoutHandle = ' + jt_audioTimeoutHandle);
    }
    else if (jt_audioTimeoutHandle != null) {
        clearTimeout(jt_audioTimeoutHandle);
        jt_audioTimeoutHandle = null;
    }
}

function jt_onAudioEnded() {
    //alert('ended called');
    if (jt_audioFiles == null)
        return;
    while (jt_audioControl.position < jt_audioControl.duration)
        ;
    jt_audioFileIndex = jt_audioFileIndex + 1;
    if (jt_audioFileIndex < jt_audioFiles.length) {
        jt_createAudio(jt_audioFiles[jt_audioFileIndex]);
    }
    else {
        jt_audioControl.pause();
        jt_audioFiles = null;
        jt_audioFileIndex = 0;
    }
}

function jt_onAudioError(e) {
    var msg;
    switch (e.target.error.code) {
        case e.target.error.MEDIA_ERR_ABORTED:
            msg = 'You aborted the video playback.';
            break;
        case e.target.error.MEDIA_ERR_NETWORK:
            msg = 'A network error caused the video download to fail part-way.';
            break;
        case e.target.error.MEDIA_ERR_DECODE:
            msg = 'The video playback was aborted due to a corruption problem or because the video used features your browser did not support.';
            break;
        case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
            msg = 'The video could not be loaded, either because the server or network failed or because the format is not supported.';
            break;
        default:
            msg = 'An unknown error occurred.';
            break;
    }
    alert('Error loading media: ' + msg + ' Media file: ' + jt_audioFile + ' MIME type: ' + jt_audioMimeType);
}

function jt_addSource(url) {
    var srcUrl;
    var doConvertCheck = false;
    var offset = url.lastIndexOf(".");
    if (offset == -1) {
        if (jt_audioSource == null) {
            jt_audioSource = document.createElement('source');
            jt_audioControl.appendChild(jt_audioSource);
        }
        jt_audioMimeType = 'audio/mpeg3';
        jt_audioMediaType = 'audio/mpeg3';
        jt_audioSource.type = jt_audioMediaType;
        jt_audioSource.src = url;
        jt_audioControl.load();
        return;
    }
    var base = url.substr(0, offset);
    var ext = url.substr(offset).toLowerCase();
    var newExt = ext;
    if (jt_audioControl.canPlayType('audio/mpeg3')) {
        jt_audioMimeType = 'audio/mpeg3';
        jt_audioMediaType = 'audio/mpeg3';
        if (ext != '.mp3')
            newExt = '-aa.mp3';
    }
    else if (jt_audioControl.canPlayType('audio/mpeg')) {
        jt_audioMimeType = 'audio/mpeg3';
        jt_audioMediaType = 'audio/mpeg';
        if (ext != '.mp3')
            newExt = '-aa.mp3';
    }
    else if (jt_audioControl.canPlayType('audio/mp3')) {
        jt_audioMimeType = 'audio/mpeg3';
        jt_audioMediaType = 'audio/mp3';
        if (ext != '.mp3')
            newExt = '-aa.mp3';
    }
    else if (jt_audioControl.canPlayType('audio/ogg')) {
        jt_audioMimeType = 'audio/ogg';
        jt_audioMediaType = 'audio/ogg';
        if (ext != '.ogg')
            newExt = '-aa.ogg';
    }
    else {
        alert('Sorry, can not play file: ' + url);
    }
    srcUrl = base + newExt;
    if (srcUrl.lastIndexOf('~', 0) === 0) {
        if (window.location.hostname == '') {
            srcUrl = srcUrl.substr(2);
        }
        else {
            var url = 'http://' + window.location.hostname;
            if (window.location.port.toString() != '')
                url = usrl + ':' + window.location.port.toString()
            srcUrl = url + srcUrl.substr(1);
        }
    }
    //alert('srcUrl = ' + srcUrl);
    if (jt_audioSource == null) {
        jt_audioSource = document.createElement('source');
        jt_audioControl.appendChild(jt_audioSource);
    }
    jt_audioSource.type = jt_audioMediaType;
    if (doConvertCheck) {
        jt_audioLink = "/ConvertCheck?path=" + srcUrl + "&" + "mimeType=" + jt_audioMimeType
        jt_audioSource.src = jt_audioLink;
    }
    else {
        jt_audioSource.src = srcUrl;
    }
    jt_audioControl.load();
}

function jt_extractTimeRange(url) {
    var rangeFieldIndex = url.lastIndexOf("#t");
    if (rangeFieldIndex >= 0) {
        var rangeString = url.substr(rangeFieldIndex + 2);
        var range = rangeString.split(',');
        jt_audioStartTime = parseFloat(range[0]);
        jt_audioEndTime = parseFloat(range[1]);
    }
    else {
        jt_audioStartTime = 0.0;
        jt_audioEndTime = 0.0;
        return url;
    }
    return url.substr(0, rangeFieldIndex);
}

function jt_createAudio(url) {
    url = jt_extractTimeRange(url);
    if (jt_audioControl == null) {
        jt_audioFile = url;
        jt_audioControl = new Audio();
        // The ontimeupdate handler seems to be called unreliably, so we'll use
        // setTimeout as well in the oncanplay handler.
        jt_audioControl.ontimeupdate = jt_onAudioTimeUpdate;
        jt_audioControl.onloadedmetadata = jt_onAudioCanPlay;
        jt_audioControl.onended = jt_onAudioEnded;
        jt_audioControl.onerror = jt_onAudioError;
        jt_addSource(url);
        // We'll let the oncanplay call play once loaded.
    }
    else if (jt_audioFile != url) {
        jt_audioFile = url;
        jt_addSource(url);
    }
    else {
        //jt_onAudioLoaded();
        jt_audioControl.load();
    }
}

function jt_playAudioFile(url) {
    jt_audioFiles = null;
    jt_audioFileIndex = 0;
    jt_audioStartTime = 0.0;
    jt_audioEndTime = 0.0;
    jt_audioPlaybackRate = 1.0;
    jt_createAudio(url);
}

function jt_playSlowAudioFile(url) {
    jt_audioFiles = null;
    jt_audioFileIndex = 0;
    jt_audioStartTime = 0.0;
    jt_audioEndTime = 0.0;
    jt_audioPlaybackRate = 0.5;
    jt_createAudio(url);
}

function jt_playAudioFileList(urls) {
    jt_audioFiles = urls;
    jt_audioFileIndex = 0;
    jt_audioStartTime = 0.0;
    jt_audioEndTime = 0.0;
    jt_audioPlaybackRate = 1.0;
    if ((urls != null) && (urls.length > 0)) {
        jt_createAudio(urls[0]);
    }
}

function jt_playSlowAudioFileList(urls) {
    jt_audioFiles = urls;
    jt_audioFileIndex = 0;
    jt_audioStartTime = 0.0;
    jt_audioEndTime = 0.0;
    jt_audioPlaybackRate = 0.5;
    if ((urls != null) && (urls.length > 0)) {
        jt_createAudio(urls[0]);
    }
}

function jt_playAudioFileSegment(url, startTime, endTime) {
    jt_audioFiles = null;
    jt_audioFileIndex = 0;
    url = url + '#t' + startTime.toString() + ',' + endTime.toString();
    jt_audioPlaybackRate = 1.0;
    jt_createAudio(url);
}

function jt_playSlowAudioFileSegment(url, startTime, endTime) {
    jt_audioFiles = null;
    jt_audioFileIndex = 0;
    url = url + '#t' + startTime.toString() + ',' + endTime.toString();
    jt_audioPlaybackRate = 0.5;
    jt_createAudio(url);
}

function jt_stopAudio() {
    if (jt_audioControl != null)
        jt_audioControl.pause();
}

function jt_volumeSliderChanged() {
    if (jt_volumeSlider == null) {
        jt_volumeSlider = document.getElementById('volumeSlider');
        if (jt_volumeSlider == null)
            return;
    }
    var value = jt_volumeSlider.value;
    if (jt_audioControl != null)
        jt_audioControl.volume = value / 10;
    $.ajax({
        url: "/Common/SetUserOptionAjax?key=AudioVolume&value=" + value.toString(),
        type: "POST"
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.