gpt4 book ai didi

javascript - 如何仅解码部分 mp3 以与 WebAudio API 一起使用?

转载 作者:搜寻专家 更新时间:2023-11-01 04:35:47 25 4
gpt4 key购买 nike

在我的网络应用程序中,我需要播放 mp3 文件的一部分。这是一个本地网络应用程序,所以我不关心下载等,一切都存储在本地。

我的用例如下:

  • 确定要播放的文件
  • 确定声音的开始和结束
  • 加载文件[我使用BufferLoader]

非常简单。

现在我只是抓取 mp3 文件,在内存中对其进行解码以便与 WebAudio API 一起使用,然后播放它。不幸的是,由于 mp3 文件可能会变得很长 [例如 30 分钟的音频],因此内存中的解码文件最多可能占用 900MB。这有点太多了。

有什么选项可以让我只解码文件的一部分吗?我怎样才能检测到从哪里开始以及要走多远?我无法预测比特率,它可以是恒定的,但我希望它也是可变的。

这是我所做的一个例子: http://tinyurl.com/z9vjy34

代码[我试图让它尽可能紧凑]:

var MediaPlayerAudioContext = window.AudioContext || window.webkitAudioContext;

var MediaPlayer = function () {
this.mediaPlayerAudioContext = new MediaPlayerAudioContext();
this.currentTextItem = 0;
this.playing = false;
this.active = false;
this.currentPage = null;
this.currentAudioTrack = 0;
};

MediaPlayer.prototype.setPageNumber = function (page_number) {
this.pageTotalNumber = page_number
};

MediaPlayer.prototype.generateAudioTracks = function () {
var audioTracks = [];
var currentBegin;
var currentEnd;
var currentPath;
audioTracks[0] = {
begin: 4.300,
end: 10.000,
path: "example.mp3"
};
this.currentPageAudioTracks = audioTracks;
};

MediaPlayer.prototype.show = function () {
this.mediaPlayerAudioContext = new MediaPlayerAudioContext();
};

MediaPlayer.prototype.hide = function () {
if (this.playing) {
this.stop();
}
this.mediaPlayerAudioContext = null;
this.active = false;
};

MediaPlayer.prototype.play = function () {
this.stopped = false;
console.trace();

this.playMediaPlayer();
};

MediaPlayer.prototype.playbackStarted = function() {
this.playing = true;
};

MediaPlayer.prototype.playMediaPlayer = function () {
var instance = this;

var audioTrack = this.currentPageAudioTracks[this.currentAudioTrack];
var newBufferPath = audioTrack.path;

if (this.mediaPlayerBufferPath && this.mediaPlayerBufferPath === newBufferPath) {

this.currentBufferSource = this.mediaPlayerAudioContext.createBufferSource();
this.currentBufferSource.buffer = this.mediaPlayerBuffer;
this.currentBufferSource.connect(this.mediaPlayerAudioContext.destination);

this.currentBufferSource.onended = function () {
instance.currentBufferSource.disconnect(0);
instance.audioTrackFinishedPlaying()
};

this.playing = true;
this.currentBufferSource.start(0, audioTrack.begin, audioTrack.end - audioTrack.begin);

this.currentAudioStartTimeInAudioContext = this.mediaPlayerAudioContext.currentTime;
this.currentAudioStartTimeOffset = audioTrack.begin;
this.currentTrackStartTime = this.mediaPlayerAudioContext.currentTime - (this.currentTrackResumeOffset || 0);
this.currentTrackResumeOffset = null;

}
else {
function finishedLoading(bufferList) {
instance.mediaPlayerBuffer = bufferList[0];
instance.playMediaPlayer();
}

if (this.currentBufferSource){
this.currentBufferSource.disconnect(0);
this.currentBufferSource.stop(0);
this.currentBufferSource = null;
}

this.mediaPlayerBuffer = null;
this.mediaPlayerBufferPath = newBufferPath;
this.bufferLoader = new BufferLoader(this.mediaPlayerAudioContext, [this.mediaPlayerBufferPath], finishedLoading);
this.bufferLoader.load();
}
};

MediaPlayer.prototype.stop = function () {
this.stopped = true;
if (this.currentBufferSource) {
this.currentBufferSource.onended = null;
this.currentBufferSource.disconnect(0);
this.currentBufferSource.stop(0);
this.currentBufferSource = null;

}
this.bufferLoader = null;
this.mediaPlayerBuffer = null;
this.mediaPlayerBufferPath = null;
this.currentTrackStartTime = null;
this.currentTrackResumeOffset = null;
this.currentAudioTrack = 0;

if (this.currentTextTimeout) {
clearTimeout(this.currentTextTimeout);
this.textHighlightFinished();
this.currentTextTimeout = null;
this.currentTextItem = null;
}

this.playing = false;
};

MediaPlayer.prototype.getNumberOfPages = function () {
return this.pageTotalNumber;
};

MediaPlayer.prototype.playbackFinished = function () {

this.currentAudioTrack = 0;
this.playing = false;

};

MediaPlayer.prototype.audioTrackFinishedPlaying = function () {

this.currentAudioTrack++;

if (this.currentAudioTrack >= this.currentPageAudioTracks.length) {
this.playbackFinished();
} else {
this.playMediaPlayer();
}
};

//
//
// Buffered Loader
//
// Class used to get the sound files
//
function BufferLoader(context, urlList, callback) {
this.context = context;
this.urlList = urlList;
this.onload = callback;
this.bufferList = [];
this.loadCount = 0;
}

// this allows us to handle media files with embedded artwork/id3 tags
function syncStream(node) { // should be done by api itself. and hopefully will.
var buf8 = new Uint8Array(node.buf);
buf8.indexOf = Array.prototype.indexOf;
var i = node.sync, b = buf8;
while (1) {
node.retry++;
i = b.indexOf(0xFF, i);
if (i == -1 || (b[i + 1] & 0xE0 == 0xE0 )) break;
i++;
}
if (i != -1) {
var tmp = node.buf.slice(i); //carefull there it returns copy
delete(node.buf);
node.buf = null;
node.buf = tmp;
node.sync = i;
return true;
}
return false;
}

BufferLoader.prototype.loadBuffer = function (url, index) {
// Load buffer asynchronously
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";

var loader = this;

function decode(sound) {
loader.context.decodeAudioData(
sound.buf,
function (buffer) {
if (!buffer) {
alert('error decoding file data');
return
}
loader.bufferList[index] = buffer;
if (++loader.loadCount == loader.urlList.length)
loader.onload(loader.bufferList);
},
function (error) {
if (syncStream(sound)) {
decode(sound);
} else {
console.error('decodeAudioData error', error);
}
}
);
}

request.onload = function () {
// Asynchronously decode the audio file data in request.response
var sound = {};
sound.buf = request.response;
sound.sync = 0;
sound.retry = 0;
decode(sound);
};
request.onerror = function () {
alert('BufferLoader: XHR error');
};
request.send();
};

BufferLoader.prototype.load = function () {
for (var i = 0; i < this.urlList.length; ++i)
this.loadBuffer(this.urlList[i], i);
};

最佳答案

无法使用 decodeAudioData() 进行流式传输,您需要将 MediaElement 与 createMediaStreamSource 一起使用,然后运行您的内容。 decodeAudioData() 无法在某个部分进行流式传输。@zre00ne 并且 mp3 将被解码大!!!非常大!!!

关于javascript - 如何仅解码部分 mp3 以与 WebAudio API 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35436771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com