栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用Content-Range在Node.js中流式传输音频

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Content-Range在Node.js中流式传输音频

我正在使用

expressjs
框架,并且已经做到了:

// Readable Streams Storage Classclass FileReadStreams {  constructor() {    this._streams = {};  }  make(file, options = null) {    return options ?      fs.createReadStream(file, options)      : fs.createReadStream(file);  }  get(file) {    return this._streams[file] || this.set(file);  }  set(file) {    return this._streams[file] = this.make(file);  }}const readStreams = new FileReadStreams();// Getting file stats and caching it to avoid disk i/ofunction getFileStat(file, callback) {  let cacheKey = ['File', 'stat', file].join(':');  cache.get(cacheKey, function(err, stat) {    if(stat) {      return callback(null, stat);    }    fs.stat(file, function(err, stat) {      if(err) {        return callback(err);      }      cache.set(cacheKey, stat);      callback(null, stat);    });  });}// Streaming whole filefunction streamFile(file, req, res) {  getFileStat(file, function(err, stat) {    if(err) {      console.error(err);      return res.status(404);    }    let bufferSize = 1024 * 1024;    res.writeHead(200, {      'Cache-Control': 'no-cache, no-store, must-revalidate',      'Pragma': 'no-cache',      'Expires': 0,      'Content-Type': 'audio/mpeg',      'Content-Length': stat.size    });    readStreams.make(file, {bufferSize}).pipe(res);  });}// Streaming chunkfunction streamFileChunked(file, req, res) {  getFileStat(file, function(err, stat) {    if(err) {      console.error(err);      return res.status(404);    }    let chunkSize = 1024 * 1024;    if(stat.size > chunkSize * 2) {      chunkSize = Math.ceil(stat.size * 0.25);    }    let range = (req.headers.range) ? req.headers.range.replace(/bytes=/, "").split("-") : [];    range[0] = range[0] ? parseInt(range[0], 10) : 0;    range[1] = range[1] ? parseInt(range[1], 10) : range[0] + chunkSize;    if(range[1] > stat.size - 1) {      range[1] = stat.size - 1;    }    range = {start: range[0], end: range[1]};    let stream = readStreams.make(file, range);    res.writeHead(206, {      'Cache-Control': 'no-cache, no-store, must-revalidate',      'Pragma': 'no-cache',      'Expires': 0,      'Content-Type': 'audio/mpeg',      'Accept-Ranges': 'bytes',      'Content-Range': 'bytes ' + range.start + '-' + range.end + '/' + stat.size,      'Content-Length': range.end - range.start + 1,    });    stream.pipe(res);  });}router.get('/:file/stream', (req, res) => {  const file = path.join('path/to/mp3/', req.params.file+'.mp3');  if(/firefox/i.test(req.headers['user-agent'])) {    return streamFile(file, req, res);  }  streamFileChunked(file, req, res);});

网站的完整资源在这里

尝试修复您的代码:

这将强制浏览器对资源进行分块处理。

var header = {    'Content-Length': range[1],    'Content-Type': type,    'Access-Control-Allow-Origin': req.headers.origin || "*",    'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',    'Access-Control-Allow-Headers': 'POST, GET, OPTIONS',    'Cache-Control': 'no-cache, no-store, must-revalidate',    'Pragma': 'no-cache',    'Expires': 0  };  if(/firefox/i.test(req.headers['user-agent'])) {      res.writeHead(200, header);  }  else {    header['Accept-Ranges'] = 'bytes';    header['Content-Range'] = 'bytes ' + range[0] + '-' + range[1] + '/' + total;    header['Content-Length'] = range[2];    res.writeHead(206, header);  }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/448720.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号