前几天,一个同事说他写的web静态服务器不支持音视频的播放,现简单实现一下。

原理:实现http1.1协议的range部分。

其实这一点都不神秘,我们常用的下载工具,如迅雷,下载很快,还支持断点续传,就是利用http协议的range和多线程实现的。假如下载一个1MB的文件,如果开一个线程下载,那么只能从头到尾依次下载这个文件,这样不可能提升速度。通常,下载工具会开很多个线程,这里暂且假设是4个,然后这4个线程同时分别下载这1MB的0~255KB、256-511KB、512~767KB和768~1024KB,很显然,理论上速度提升了4倍。

那么怎么将服务器上的1MB文件分成4份呢?这就是range的强大功能了!

当请求下载文件时,带有

  Range: bytes=0-255[,256-511]  //这里表示0~255个字节,如果请求多个分段,用逗号隔开

服务器响应请求时发现头部带有Range,那么做出响应:

  Content-Range: bytes 0-255/789  //789就是整个文件的大小了

  Content-Length: 256

同时status变为,而不是200,并发送这一段数据给客户端,这样客户端接收到的数据就是整个文件的一部分了!

range的请求头还可以是:

  • Range: bytes=0-  //整个文件
  • Range: bytes=-200  //最后200个字节
  • Range: bytes=200-  //200字节后的所有字节
  • Range: bytes=0-0,-1  //第一、最后一个字节

看代码如何实现

//判断是请求头中是否有range部分
if(request.headers.range){
var size = stat.size;//获取文件大小
//暂且写在这里
function getRange(){
var range = request.headers.range; if(range.indexOf(",") != -1){//这里只处理了一个分段的情况
return false;
}
//range大约长这样子:bytes=0-255[,256-511]
var parts = range.replace(/bytes=/, '').split("-");
var partiaStart = parts[0];
var partialEnd = parts[1]; var start = parseInt(partiaStart);//起始位置
//如果是bytes=0-,就是整个文件大小了
var end = partialEnd ? parseInt(partialEnd) : size - 1; if(isNaN(start) || isNaN(end)) return false;
//分段的大小
var chunkSize = end - start + 1; return {'start': start, 'end': end, 'chunkSize': chunkSize};
} var rangeData = getRange();
if(rangeData){
//createReadStream这东西原生支持range,是不是很爽?
var raw = fs.createReadStream(realPath, {'start': rangeData.start, 'end': rangeData.end});
//状态码当然是206了
response.writeHead(206, 'Partial Content', {
'Content-Type' : contentType,
'Content-Range' : 'bytes ' + rangeData.start + '-' + rangeData.end + '/' + size,
'Content-Length' : rangeData.chunkSize
});
raw.pipe(response);
}else{
response.writeHead(416, "not ok!");
response.end();
}
}else{
//状态码200
}

大概就是这样子,其他部分略去。

用html5的audio标签试验下mp3的播放:

<audio src="audio/test.mp3" controls="controls" preload="auto" autoplay="autoplay"></audio>

得到的请求和响应头如下:

下图是MP3文件加载到6MB时的截图,这时音乐已经播放超过一半了,所以可不是加载完成才播放的。

这样web服务器就实现range功能,可以处理多媒体文件了,当然只是非常简单的实现,想了解更多可以查阅W3的网站(前面说的下载、断点续传什么的就不验证了,客户端也搞不明白)

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Nodejs实现web静态服务器对多媒体文件的支持的更多相关文章

  1. Web静态服务器

    Web静态服务器 编程微刊 Web静态服务器-1-显示固定的页面 #coding=utf-8 import socket def handle_client(client_socket): " ...

  2. Python建立web静态服务器

    原文地址:http://www.bugingcode.com/blog/python_html_web_server.html python作为工具,提供了很多好用的命令,比如有时候突然需要建立一个解 ...

  3. 08.Web服务器-3.Web静态服务器

    1.显示固定的页面 from socket import * from multiprocessing import * import os def handleClient(clientSocket ...

  4. nodejs 搭建本地静态服务器

    1. http-server 参看 https://www.npmjs.com/package/http-server 使用http-server搭建本地静态服务器 全局安装http-server n ...

  5. python高级编程之 web静态服务器

    返回固定数据 import socket def request_handler(new_client_socket): """ 响应客户端请求的核心函数 "& ...

  6. [置顶] java web 动态服务器

    写了一个java web 动态服务器,主要通过内部类来实现,动态类使用了外部类,采用了 classforname 实例化,动态类的构造方法不能带参数, 效果都出来了,分享给有需要的 朋友.判断做的不够 ...

  7. nodejs http静态服务器

    使用nodejs写的很简单的静态服务器,没有做cluster处理,没有做缓存处理,不支持访问文件夹,功能只有一个,就是获取到文件后再返回文件内容. var fs = require('fs'); va ...

  8. 安装nodeJs静态服务器(NodeJs Express MVC 框架)

    安装 NodeJs Express MVC 框架   新建项目文件夹   打开cmd 执行以下操作:   一.使用Express框架 1)安装express3 $: npm install -g ex ...

  9. Web前端页面的浏览器兼容性测试心得(一)搭建测试用本地静态服务器

    自从实习以来,我体验了由一个人编程再到多人协作编程的转换.同时也接触了很多新鲜事物,学到了很多东西.工作时,常常需要多个人协同测试一张H5页面(PC.手机.平板等跨设备测试),也会经常把页面给PM或老 ...

随机推荐

  1. linux 进程控制笔记

    进程创建 普通函数调用完成后,最多返回(return)一次,但fork/vfork会返回二次,一次返回给父进程,一次返回给子进程 父进程的返回值为子进程的进程ID,子进程的返回值为0 1.pid_t ...

  2. 管理口令(P):[INS-30001] ADMIN口令为空之Oracle安装

    在安装oracle database11g 发行版的时候出现下面这个问题. 无论怎么输入密码都提示有问题,都输入得鬼火了!去百度了一下,果然有命名规则的 规则如下:小写字母+数字+大写字母

  3. eclipse增加浏览器chrome

    1.安装完了google chrome游览器后,如何让eclipse直接用chrome打开jsp 2.添加到eclipse环境中即可, Window(菜单) -- preferences 增加成功后, ...

  4. Redis 三:存储类型之字符串

    .赋值单个: [赋值多个:mset a b c ] .取值单个: get a [取值多个:mget a b c] .数字递增 incr a 在a的基础上+,那就是返回101 如果预先的值为0,那么返回 ...

  5. linux下bus,device,driver三者关系

    linux下bus,device,driver三者关系 1.bus: 总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议.如 PCI,USB,1394,IIC等.任何设备都可以选择合适 ...

  6. nodejs是单线程

    你不妨先思考一个问题:在单核时代,PHP之类多线程或者多进程的,是怎么处理并发的?是排队吗? 答案是:的确就是排队.但是并不是一定要处理完请求1才能去处理请求2:实际上请求的处理过程中,有很多的时间是 ...

  7. 【js】js 让图片旋转

     转http://www.cnblogs.com/ustcyc/p/3760116.html 核心: canvas.style.filter = "progid:DXImageTransfo ...

  8. 瞧一瞧,看一看呐,用MVC+EF快速弄出一个CRUD,一行代码都不用写,真的一行代码都不用写!!!!

    瞧一瞧,看一看呐用MVC+EF快速弄出一个CRUD,一行代码都不用写,真的一行代码都不用写!!!! 现在要写的呢就是,用MVC和EF弄出一个CRUD四个页面和一个列表页面的一个快速DEMO,当然是在不 ...

  9. 2876: [Noi2012]骑行川藏 - BZOJ

    Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...

  10. 2815: [ZJOI2012]灾难 - BZOJ

    题目描述 Description 阿米巴是小强的好朋友.    阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的 ...