如何为现有MP3流式传输/下载Express服务器添加快进快退功能?
实现Express MP3服务器的快进快退功能
要实现快进快退,核心是处理HTTP的Range请求——这是浏览器/客户端向服务器请求资源特定字节范围的标准机制,服务器返回对应片段并返回206 Partial Content状态码,就能让播放器支持跳转操作。下面是具体的实现方案,直接改造你的Express服务器即可:
改造步骤与完整代码
替换你现有服务器中的/stream路由,改成以下实现:
const express = require('express'); const fs = require('fs'); const { stat } = require('fs/promises'); // 用Promise版本更简洁易维护 const app = express(); app.use('/mp3', express.static(__dirname + '/mp3')); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.get('/stream', async (req, res) => { const filePath = __dirname + '/mp3/trololol.mp3'; try { const fileStats = await stat(filePath); const fileSize = fileStats.size; const range = req.headers.range; // 处理客户端发送的Range请求头 if (range) { // 解析Range格式:bytes=start-end const parts = range.replace(/bytes=/, "").split("-"); const start = parseInt(parts[0], 10); // 如果end未指定,默认到文件末尾 const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1; // 校验Range范围是否合法 if (start >= fileSize || end >= fileSize || start > end) { res.status(416).header('Content-Range', `bytes */${fileSize}`).send(); return; } const chunkSize = (end - start) + 1; // 创建指定字节范围的读取流 const rstream = fs.createReadStream(filePath, { start, end }); // 设置响应头,告知客户端返回的是部分内容 res.writeHead(206, { 'Content-Range': `bytes ${start}-${end}/${fileSize}`, 'Accept-Ranges': 'bytes', 'Content-Length': chunkSize, 'Content-Type': 'audio/mpeg', }); rstream.pipe(res); } else { // 无Range请求时返回完整文件,兼容不支持范围请求的旧客户端 res.writeHead(200, { 'Content-Length': fileSize, 'Content-Type': 'audio/mpeg', }); fs.createReadStream(filePath).pipe(res); } } catch (err) { // 处理各类错误场景 if (err.code === 'ENOENT') { res.status(404).send('MP3 file not found'); } else { res.status(500).send('Server error'); } } }); const PORT = 3000; app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });
关键细节解释
- Range请求逻辑:当用户在播放器上快进/快退时,浏览器的
<audio>标签会自动发送Range请求头(格式类似bytes=100000-),请求指定起始字节后的内容。 - 响应头核心设置:
Content-Range:告诉客户端当前返回的字节范围和文件总大小Accept-Ranges: bytes:明确告知服务器支持字节范围请求206 Partial Content:标识返回的是资源的一部分,而非完整资源
- 错误边界处理:
- 若请求的范围超出文件大小,返回
416 Range Not Satisfiable状态码 - 捕获文件不存在的异常,返回
404提示
- 若请求的范围超出文件大小,返回
测试方式
- 在你的
index.html中添加音频标签,指向/stream接口:<audio controls> <source src="/stream" type="audio/mpeg"> Your browser does not support the audio element. </audio> - 启动服务器后访问
http://localhost:3000,拖动音频进度条即可测试快进快退功能。 - 也可以用curl手动模拟Range请求:
curl -v -H "Range: bytes=0-1000" http://localhost:3000/stream
这样改造后,你的服务器就完全符合HTTP流媒体标准,支持MP3的快进快退操作了。
内容的提问来源于stack exchange,提问作者inertia
相关产品推荐
相关产品推荐

