前几天,一个同事说他写的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. jar 命令打war包

    假定有一个Web应用:C:\myHomemyHome/WEB-INF/……myHome/files/……myHome/image/……myHome/src/……myHome/index.jsp在命令行 ...

  2. django 更新model

    修改models.py 中对应的class 在admin.py 中 增加 admin.site.register(WafDevice) 进入dbshell python manage.py dbshe ...

  3. 16、WPF中的命令

    一.前言 事件的作用是发布.传播一些信息,消息送达接收者,事件的使命就算完成了,至于如何响应事件送来的消息事件并不做规定,每个接收者可以使用自己的行为来响应事件,也就是说事件不具有约束力.命令能够在代 ...

  4. Android开发——AsyncTask详解

    android提供AsynvTask,目的是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. Android为了降低开发难度,提供了AsyncTask.Asyn ...

  5. 从Keil 4升级到Keil 5的工程,想返回来用Keil 4打开

    情景描述: 笔者电脑程序Keil 4升级到Keil 5,相应地,原来项目上的工程也在第一次用Keil 5打开的时候进行了升级.之后,由于客户需要开发资料,其版本为Keil 4,我尝试着用Keil 4打 ...

  6. openstack安装、卸载与启动

    一.安装: 更新: sudo apt-get update sudo apt-get upgrade 安装图形化界面: sudo apt-get install ubuntu-desktop 安装gc ...

  7. bnuoj 33647 Angry Grammar Nazi(字符串)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=33647 [题意]:字符串匹配,暴力配就行了 [题解]:截出单词,然后进行匹配就行了 [code]: ...

  8. NopCommerce——Web层中的布局页

    援引上一篇文章关于nopcommerce源代码结构的翻译:“Nop.Web也是一个MVC Web应用程序项目,一个公有区域的展示层.它就是你实际能够运行的应用程序.它是应用程序的启动项目”.对于nop ...

  9. iOS上用FTGL显示定制Truetype字体碰到的问题

    没想到这个问题搞了快2个月时间:当然跟我只是断断续续地工作有关. FTGL是freetype的opengl实现.我接触FTGL最初只是为了练习OpenGL,写几个简单的游戏app.开始试了试FTGL觉 ...

  10. BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1051 题解: 强连通缩点得到DAG图,将图转置一下,对入度为零的点跑dfs看看能不能访问 ...