You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为现有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提示

测试方式

  1. 在你的index.html中添加音频标签,指向/stream接口:
    <audio controls>
      <source src="/stream" type="audio/mpeg">
      Your browser does not support the audio element.
    </audio>
    
  2. 启动服务器后访问http://localhost:3000,拖动音频进度条即可测试快进快退功能。
  3. 也可以用curl手动模拟Range请求:
    curl -v -H "Range: bytes=0-1000" http://localhost:3000/stream
    

这样改造后,你的服务器就完全符合HTTP流媒体标准,支持MP3的快进快退操作了。

内容的提问来源于stack exchange,提问作者inertia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:23:42