如何获取网络电台音频流的MIME类型及检测音频比特率?
解决方案:检测网络电台的音频类型与比特率
一、通过Fetch加载片段检测音频类型
可以用Fetch请求流的前几十字节,解析音频文件的**文件头标识(Magic Number)**来判断格式——不同音频格式有独特的开头二进制特征,具体实现步骤如下:
- 用
fetch请求音频流时,通过Range头只获取前128字节(足够识别绝大多数主流音频格式) - 读取响应的ArrayBuffer,解析二进制数据匹配对应格式
- 确认格式后,再将完整流交给Audio元素播放
示例代码:
async function detectAudioFormat(streamUrl) { try { // 请求前128字节,减少资源消耗 const response = await fetch(streamUrl, { headers: { 'Range': 'bytes=0-127' } }); if (!response.ok) throw new Error('请求片段失败'); const buffer = await response.arrayBuffer(); const view = new Uint8Array(buffer); // 匹配各格式的特征标识 // MP3:开头为ID3标签(0x494433)或帧同步字 if (view[0] === 0x49 && view[1] === 0x44 && view[2] === 0x33) { return 'mp3'; } // OGG:开头为OggS(0x4F676753) if (view[0] === 0x4F && view[1] === 0x67 && view[2] === 0x67 && view[3] === 0x53) { return 'ogg'; } // AAC:ADTS头以0xFFF0开头 if ((view[0] & 0xFF) === 0xFF && (view[1] & 0xF0) === 0xF0) { return 'aac'; } // 可根据需求补充WAV、FLAC等其他格式的检测逻辑 return 'unknown'; } catch (err) { console.error('检测格式出错:', err); return 'unknown'; } } // 使用示例 const streamUrl = 'https://some-radio-station.com/stream'; detectAudioFormat(streamUrl).then(format => { console.log('音频类型:', format); // 格式检测完成后初始化播放器 const audio = new Audio(); audio.addEventListener('loadeddata', () => audio.play()); audio.src = streamUrl; });
注意:部分电台服务器可能不支持Range请求,这种情况下可以尝试读取响应的Content-Type头,但多数流媒体的该字段仅为audio/mpeg这类通用类型,无法精确到具体格式,因此解析文件头是更可靠的方案。
二、检测音频比特率
比特率检测分两种场景实现:
1. 从文件头解析(针对带元数据的格式)
主流音频格式的文件头会携带比特率信息,直接解析对应字段即可:
- MP3:解析ID3标签或帧头的比特率索引
- AAC:读取ADTS头的比特率参数
- OGG:提取Vorbis头中的比特率数据
以MP3为例的解析代码:
function getMP3Bitrate(buffer) { const view = new Uint8Array(buffer); let offset = 0; // 跳过ID3标签(如果存在) if (view[0] === 0x49 && view[1] === 0x44 && view[2] === 0x33) { const tagSize = ((view[6] & 0x7F) << 21) | ((view[7] & 0x7F) << 14) | ((view[8] & 0x7F) << 7) | (view[9] & 0x7F); offset = 10 + tagSize; } // 寻找第一个MP3帧同步字(0xFFE0及以上) while (offset < view.length - 1) { if ((view[offset] === 0xFF) && ((view[offset+1] & 0xE0) === 0xE0)) { // 提取比特率索引,匹配标准比特率表 const bitrateIndex = (view[offset+2] >> 4) & 0x0F; const bitrates = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320]; return bitrates[bitrateIndex] + ' kbps'; } offset++; } return 'unknown'; } // 可在detectAudioFormat返回'mp3'时调用该函数 // detectAudioFormat(streamUrl).then(format => { // if (format === 'mp3') { // const buffer = await response.arrayBuffer(); // 需调整代码逻辑传递buffer // console.log('比特率:', getMP3Bitrate(buffer)); // } // });
2. 实时估算(适合流媒体场景)
如果无法从文件头获取比特率,可以统计一段时间内加载的数据量来估算:
function estimateBitrate(audioElement) { const startTime = Date.now(); const startBytes = audioElement.buffered.end(0); setTimeout(() => { const endTime = Date.now(); const endBytes = audioElement.buffered.end(0); const duration = (endTime - startTime) / 1000; // 转换为秒 const bytesLoaded = endBytes - startBytes; // 字节转比特,再转换为kbps const bitrate = (bytesLoaded * 8) / duration / 1000; console.log('估算比特率:', Math.round(bitrate) + ' kbps'); }, 5000); // 5秒后计算,可根据需求调整时长 } // 使用示例 const audio = new Audio(); audio.src = streamUrl; audio.addEventListener('loadeddata', () => { audio.play(); estimateBitrate(audio); });
这种方法是近似值,受流媒体波动影响,但足够满足显示需求。
内容的提问来源于stack exchange,提问作者Mik
相关产品推荐
相关产品推荐

