我希望在网页上播放有声读物。有声书是一个.zip文件,其中包含多个.mp3文件,该书的每一章都有一个。所有文件的运行时间为几个小时,其累积大小为60MB。 .zip存储在服务器端(Express.js)
如何在客户端(例如,在<audio>
元素中)连续播放每个文件,以使有声读物像1个文件一样流畅地播放? >
我需要使用MediaStream
对象吗?如果可以,怎么办?
-谢谢
答案 0 :(得分:2)
我将在另一个Stack Overflow question上查看此答案,但是为了适应您的问题,我进行了一些修改:
var audioFileURLs= [];
function preloadAudio(url) {
var audio = new Audio();
// once this file loads, it will call loadedAudio()
// the file will be kept by the browser as cache
audio.addEventListener('canplaythrough', loadedAudio, false);
audio.src = url;
}
var loaded = 0;
function loadedAudio() {
// this will be called every time an audio file is loaded
// we keep track of the loaded files vs the requested files
loaded++;
if (loaded == audioFileURLs.length){
// all have loaded
init();
}
}
var player = document.getElementById('player');
function play(index) {
player.src = audioFiles[index];
player.play();
}
function init() {
// do your stuff here, audio has been loaded
// for example, play all files one after the other
var i = 0;
// once the player ends, play the next one
player.onended = function() {
i++;
if (i >= audioFiles.length) {
// end
return;
}
play(i);
};
// play the first file
play(i);
}
// call node/express server to get a list of links we can hit to retrieve each audio file
fetch('/getAudioUrls/#BookNameOrIdHere#')
.then(r => r.json())
.then(arrayOfURLs => {
audioFileURLs = arrayOfURLs
arrayOfURLs.map(url => preloadAudio(URL))
})
然后在屏幕上仅显示一个音频元素,其ID为“ player”,如<audio id="player"></audio>
尽管有了这个答案,arrayOfURLs
数组必须包含指向服务器上API的URL,该URL将打开zip文件并返回指定的mp3数据。您可能还只想将此答案作为一般参考,而不是一个完整的解决方案,因为需要进行优化。您可能只应该首先加载第一个音频文件,并且在第一个文件结束前5分钟左右,您可能要开始预加载下一个音频文件,然后对整个过程重复此过程...您,但这有望使您站起来。
您可能还会遇到音频元素问题,因为它只会显示当前音频片段的长度,而不会显示有声读物的整个长度。我会选择相信此zip文件的书是否正确地按章分开了?如果是这样,您可以创建一个章节选择器,这几乎可以使您跳转到特定的章节,即getAudioUrls URL。
我希望这会有所帮助!
为您提供的另一条注释...阅读您对下面可能的答案的评论,您可以使用某种节点模块将所有音频文件合并为一个(audioconcat是我在快速搜索后找到的一个搜索)并将该文件返回给客户端。但是,我不会亲自走这条路,因为整个有声读物在将它们组合在一起时,将一直存储在服务器的内存中,直到将其返回给客户端为止。这可能会导致一些内存问题,因此,如果可以的话,我会避免它。但是,我承认该选项可能会很好,因为有声读物的全长将显示在音频元素的时间轴中。
最好的选择也许是将书籍的完整长度和章节长度存储在zip文件的details.json文件中,并在第一个API调用中将其连同URL一起发送到客户端,并发送到每个音频文件。这将使您能够构建一个不错的UI。
答案 1 :(得分:0)
我唯一想到的选择是使用javascript mp3解码器(或将C解码器编译为asm.js / wasm)并使用音频API。或使用mux.js之类的文件将mp3包装为mp4并使用媒体源扩展名进行播放。
答案 2 :(得分:-3)
也许这会对您有所帮助
<audio controls="controls">
<source src="track.ogg" type="audio/ogg" />
<source src="track.mp3" type="audio/mpeg" />
Your browser does not support the audio element.
</audio>