我正在使用JavaScript解析SWF文件,并将内容显示在HTML5画布中。
播放音频流swf标签中的音频数据时遇到问题。音频按帧分割,我可以将音频数据按与帧相同的顺序放入base64数据数组中。在每个帧上创建/销毁音频元素似乎并不是解决问题的最佳方法,但这是我能想到的唯一方法。有没有更好的方法可以解决这个问题?
注意:swf文件中也有快退/快进/暂停按钮,因此在发送回音频时,音频将需要与帧对齐,因此我不相信我只能创建一个长音频文件从较小的数据位开始。
答案 0 :(得分:1)
您将需要将这些音频文件加载为AudioBuffers,并通过Web Audio API播放它们。
您当前拥有的是数据URL,它们确实表示完整的音频文件(带有元数据)。
首先从because some browsers may not let you do so开始,然后将所有这些内容加载到Audio元素中可能不是一个好主意,因为HTMLMediaElement并不适合完美的计时。
因此,您需要首先获取所有这些数据URL,以在ArrayBuffers中获取其实际二进制内容,然后才能从这些音频文件中提取原始PCM音频数据。
// would be the same with data-URLs
const urls = [
"kbgd2jm7ezk3u3x/hihat.mp3",
"h2j6vm17r07jf03/snare.mp3",
"1cdwpm3gca9mlo0/kick.mp3",
"h8pvqqol3ovyle8/tom.mp3"
].map( (path) => 'https://dl.dropboxusercontent.com/s/' + path );
const audio_ctx = new AudioContext();
Promise.all( urls.map( toAudioBuffer ) )
.then( activateBtn )
.catch( console.error );
async function toAudioBuffer( url ) {
const resp = await fetch( url );
const arr_buffer = await resp.arrayBuffer();
return audio_ctx.decodeAudioData( arr_buffer );
}
function activateBtn( audio_buffers ) {
const btn = document.getElementById( 'btn' );
btn.onclick = playInSequence;
btn.disabled = false;
// simply play one after the other
// you could add your own logic of course
async function playInSequence() {
await audio_ctx.resume(); // to make noise we need to be allowed by a user gesture
let current = 0;
while( current < audio_buffers.length ) {
// create a bufferSourceNode, no worry, it weights nothing
const source = audio_ctx.createBufferSource();
source.buffer = audio_buffers[ current ];
// so it makes noise
source.connect( audio_ctx.destination );
// [optional] promisify
const will_stop = new Promise( (res) => source.onended = res );
source.start(0); // start playing now
await will_stop;
current ++;
}
}
}
<button id="btn" disabled>play all in sequence</button>
答案 1 :(得分:0)
我最终在javascript中创建了一个声音ID索引的数组,该索引与帧ID相对应,并且在对象内部包含了一个音频元素,当我解析标签时会创建该音频元素。元素没有添加到DOM中,而是在前面创建的,因此它们在帧处理程序的生命周期中一直存在(因为它们存储在对象内部的sounds数组中),因此没有创建/存储的成本
这样,当我播放帧(视觉效果)时,可以调用与活动帧相对应的音频元素上的播放。当帧控制播放哪种音频时,后退/快进功能将保留。