node stream 在網(wǎng)頁視頻中的應(yīng)用

“Streams are Node’s best and most misunderstood idea.”
— Dominic Tarr

大家好,我是曲靈風(fēng)乒躺,這段時間看node stream的東西勺三,想通過stream做一玩意兒,最后搞了一個視頻站的東西(手機(jī)排版沒做好,電腦排版還可以)悲没。

視頻站截圖.png

訪問
源碼位置

先聲明一下,這里用到的技術(shù)有點多男图,因為本文是針對stream的示姿,其他的東西會一筆帶過,涉及到流的東西會詳細(xì)逊笆。

上正文栈戳,想必大家都知道,使用流的兩大優(yōu)勢是

  1. 處理大量數(shù)據(jù)难裆。
  2. 組合代碼子檀,例如使用pipe。

這里的具體解釋可以查看參考資料的 Node.js Streams: Everything you need to know乃戈。

既然stream可以處理大量數(shù)據(jù)褂痰,那么處理視頻這樣的文件就可以使用stream。

先看app.js

var express = require('express');
var app = express();
var port = process.env.PORT || 3000;

app.set('views', __dirname + '/views');

app.set('view engine', 'ejs');

app.use(require('./controllers'));

app.listen(port, function () {
    console.log('listen to port:' + port);
});

獲取了一個應(yīng)用程序?qū)嵗齛pp(相當(dāng)于new一個應(yīng)用程序?qū)嵗?症虑;
設(shè)置模板文件存放的目錄缩歪;
設(shè)置模板引擎為ejs
路由在app.use(require('./controllers'))設(shè)置谍憔;
最后監(jiān)聽端口匪蝙。

具體程序應(yīng)用框架的架構(gòu)可以參考我的文章
通過express實現(xiàn)一個簡單的MVC

通過路由到達(dá)文件movie.js

var express = require('express');
var router = express.Router();
var fs = require('fs');

router.get('/', function(req, res){
    
    var path = 'video/shanghaiTan.mp4';
    var stat = fs.statSync(path);
    var fileSize = stat.size;
    var range = req.headers.range;

    var parts = range.replace(/bytes=/, "").split("-")
    var start = parseInt(parts[0], 10);
    var end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;

    var chunksize = (end-start) + 1;
    var file = fs.createReadStream(path, {start, end})
    var head = {
        'Content-Range': `bytes ${start}-${end}/${fileSize}`,
        'Accept-Ranges': 'bytes',
        'Content-Length': chunksize,
        'Content-Type': 'video/mp4',
    }
    res.writeHead(206, head);
    file.pipe(res);
});

module.exports = router;

這里是stream主要應(yīng)用的地方主籍,通過使用stream,使得每次發(fā)送數(shù)據(jù)是一塊一塊的骗污,而并非一下子把所有的數(shù)據(jù)發(fā)送的前端崇猫。

bootstrap請求視頻默認(rèn)是Content-Range的方式,這是種部分請求的方式需忿,針對范圍請求诅炉,響應(yīng)會返回狀態(tài)碼為 206 Partial Content 的響應(yīng)報文,見下圖所示屋厘。


Content-Range.png

因為rander的格式是Range: bytes = 0 -涕烧,因此通過字符串的處理可以獲取相應(yīng)信息,從而構(gòu)建響應(yīng)頭汗洒。
最后通過可讀流的pipe方法寫到可寫流(response對象中)议纯。

所有流都是事件(EventEmitter)的實例,因此可以監(jiān)聽事件溢谤。而pipe方法的實現(xiàn)原理是就是通過對dataend事件的監(jiān)聽獲取數(shù)據(jù)的瞻凤,其中pipe還利用了后壓機(jī)制,是流比較好的實現(xiàn)方式世杀。

其實為了做這個東西阀参,著實是踩了不少坑,例如:

  1. 訪問服務(wù)器端口不成功瞻坝,在知乎上問問題蛛壳。
  2. 'Content-Type': 'video/mp4',這里的設(shè)置只會播放mp4中編碼是H.264所刀,其他編碼視頻可能不顯示衙荐。
    詳細(xì)的問題,最后通過網(wǎng)上的一個Node依賴實現(xiàn)的浮创。
  3. bootstrap也是第一次使用忧吟,也踩了不少坑??。
    希望各位看官不要再掉坑里了斩披,最后獎勵自己一朵小紅花??瀑罗。

參考資料

Node.js Streams: Everything you need to know
Video stream with Node.js and HTML5
Basic use of Node.js streams
Node.js Streams by Example

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市雏掠,隨后出現(xiàn)的幾起案子斩祭,更是在濱河造成了極大的恐慌,老刑警劉巖乡话,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摧玫,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诬像,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門屋群,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坏挠,你說我怎么就攤上這事芍躏。” “怎么了降狠?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵对竣,是天一觀的道長。 經(jīng)常有香客問我榜配,道長否纬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任蛋褥,我火速辦了婚禮临燃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烙心。我一直安慰自己膜廊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布淫茵。 她就那樣靜靜地躺著溃论,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痘昌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天炬转,我揣著相機(jī)與錄音辆苔,去河邊找鬼。 笑死扼劈,一個胖子當(dāng)著我的面吹牛驻啤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荐吵,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼骑冗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了先煎?” 一聲冷哼從身側(cè)響起贼涩,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎薯蝎,沒想到半個月后遥倦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡占锯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年袒哥,在試婚紗的時候發(fā)現(xiàn)自己被綠了缩筛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡堡称,死狀恐怖瞎抛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情却紧,我是刑警寧澤桐臊,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站啄寡,受9級特大地震影響豪硅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挺物,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一懒浮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧识藤,春花似錦砚著、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赶撰,卻和暖如春舌镶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背豪娜。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工餐胀, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘤载。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓否灾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鸣奔。 傳聞我的和親對象是個殘疾皇子墨技,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)挎狸,斷路器扣汪,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • stream 流是一個抽象接口,在 Node 里被不同的對象實現(xiàn)锨匆。例如 request to an HTTP se...
    明明三省閱讀 3,406評論 1 10
  • 流是Node中最重要的組件和模式之一私痹。在社區(qū)里有一句格言說:讓一切事務(wù)流動起來。這已經(jīng)足夠來描述在Node中流...
    宮若石閱讀 552評論 0 0
  • Node.js是目前非常火熱的技術(shù)紊遵,但是它的誕生經(jīng)歷卻很奇特账千。 眾所周知,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,616評論 2 41
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,336評論 0 6