jsmpeg系列六 源碼 概要總結(jié)

一匿又、合并腳本

最終使用的jsmpeg.min.js其實(shí)就是源碼src目錄下的所有js合并而成程拭。可以自行修改筷狼,然后使用以下腳本合并運(yùn)行瓶籽。前幾個系列已經(jīng)學(xué)習(xí)了視頻解碼部分,音頻部分使用了mp2+webaudio埂材,暫時不作分析∷芩常現(xiàn)在再把剩余的幾個類簡單看一下。

var gulp = require('gulp');
var concat = require("gulp-concat");
var uglify = require('gulp-uglify');
gulp.task('concat', function() {
    gulp.src(['src/jsmpeg.js',
    'src/video-element.js',
    'src/player.js',
    'src/buffer.js',
    'src/ajax.js',
    'src/ajax-progressive.js',
    'src/websocket.js',
    'src/ts.js',
    'src/decoder.js',
    'src/mpeg1.js',
    'src/mp2.js',
    'src/webgl.js',
    'src/canvas2d.js',
    'src/webaudio.js'
    ])
    .pipe(concat('jsmpeg.min3.js'))
    //.pipe(uglify())
    .pipe(gulp.dest(''));
});

gulp.task('default', ['concat']);
二俏险、jsmpeg.js

這里封裝了命名空間及子空間严拒,入口指向了JSMpeg.CreateVideoElements

    CreateVideoElements: function() {
        var elements = document.querySelectorAll('.jsmpeg');
        for (var i = 0; i < elements.length; i++) {
            new JSMpeg.VideoElement(elements[i]);
        }
    }
三、video-element.js
    // A Video Element wraps the Player, shows HTML controls to start/pause
    // the video and handles Audio unlocking on iOS. VideoElements can be
    // created directly in HTML using the <div class="jsmpeg"/> tag.

最終指向了這里

    // Create the player instance
    this.player = new JSMpeg.Player(url, options);
    element.playerInstance = this.player;
四竖独、readme里的參數(shù)說明

The url argument accepts a URL to an MPEG .ts file or a WebSocket server (ws://...).

The options argument supports the following properties:

  • canvas – the HTML Canvas elment to use for video rendering. If none is given, the renderer will create its own Canvas element.
  • loop – whether to loop the video (static files only). Default true.
  • autoplay - whether to start playing immediately (static files only). Default false.
  • audio - whether to decode audio. Default true.
  • video - whether to decode video. Default true.
  • poster – URL to an image to use as the poster to show before the video plays.
  • pauseWhenHidden – whether to pause playback when the tab is inactive. Default true. Note that browsers usually throttle JS in inactive tabs anyway.
  • disableGl - whether to disable WebGL and always use the Canvas2D renderer. Default false.
  • preserveDrawingBuffer – whether the WebGL context is created with preserveDrawingBuffer - necessary for "screenshots" via canvas.toDataURL(). Default false.
  • progressive - whether to load data in chunks (static files only). When enabled, playback can begin before the whole source has been completely loaded. Default true.邊下邊播
  • throttled - when using progressive, whether to defer loading chunks when they're not needed for playback yet. Default true.
  • chunkSize - when using progressive, the chunk size in bytes to load at a time. Default 1024*1024 (1mb).
  • decodeFirstFrame - whether to decode and display the first frame of the video. Useful to set up the Canvas size and use the frame as the "poster" image. This has no effect when using autoplay or streaming sources. Default true.
  • maxAudioLag – when streaming, the maximum enqueued audio length in seconds.
  • videoBufferSize – when streaming, size in bytes for the video decode buffer. Default 512*1024 (512kb). You may have to increase this for very high bitrates.
  • audioBufferSize – when streaming, size in bytes for the audio decode buffer. Default 128*1024 (128kb). You may have to increase this for very high bitrates.

All options except from canvas can also be used with the HTML Element through data- attributes. E.g. to specify looping and autoplay in JavaScript:
var player = new JSMpeg.Player('video.ts' {loop: true, autoplay: true});
or HTML

<div class="jsmpeg" data-url="video.ts" 
    data-loop="true" data-autoplay="true"></div>

Note that camelCased options have to be hyphenated when used as data attributes. E.g. decodeFirstFrame: true becomes data-decode-first-frame="true" for the HTML element.

五裤唠、搭建測試環(huán)境

1.README.md
JSMpeg is a Video Player written in JavaScript. It consists of an MPEG-TS demuxer, MPEG1 video & MP2 audio decoders, WebGL & Canvas2D renderers and WebAudio sound output. JSMpeg can load static videos via Ajax and allows low latency streaming (~50ms) via WebSockets.

JSMpeg can decode 720p Video at 30fps on an iPhone 5S, works in any modern browser (Chrome, Firefox, Safari, Edge) and comes in at just 20kb gzipped.

Using it can be as simple as this:

<script src="jsmpeg.min.js"></script>
<div class="jsmpeg" data-url="video.ts"></div>

Some more info and demos: jsmpeg.com

2.jsmpeg.com的例子
查看html的element,然后下載這個示例的Ts文件

<div class="jsmpeg full-width" data-url="bjork-all-is-full-of-love.ts" style="..."</div>

發(fā)現(xiàn)本地直接打開這個html是播放不了的莹痢,需要部署到服務(wù)器上巧骚。這下可以播放本地文件了,可以參照readme加上data-loop="true" data-autoplay="true"這些控制屬性格二。

這里把div換成canvas劈彪,或者把TS本地文件變成mpg文件,都播放不了顶猜。

3.使用script代碼來播放

<body>
    <canvas id="video-canvas"></canvas>
    <script type="text/javascript" src="jsmpeg.min.js"></script>
    <script type="text/javascript">
        var canvas = document.getElementById('video-canvas');
        var player = new JSMpeg.Player('bjork-all-is-full-of-love.ts',
        {canvas:canvas,loop: true, autoplay: true});
    </script>
</body>

options參數(shù)參見readme.md

4.不支持 B-Frames沧奴,視頻寬度必須是 2 的倍數(shù)
JSMpeg only supports playback of MPEG-TS containers with the MPEG1 Video Codec and the MP2 Audio Codec. The Video Decoder does not handle B-Frames correctly (though no modern encoder seems to use these by default anyway) and the width of the video has to be a multiple of 2.

You can encode a suitable video using ffmpeg like this:

ffmpeg -i in.mp4 -f mpegts -codec:v mpeg1video -codec:a mp2 -b 0 out.ts

5.使用websocket(nginx)
這里我先嘗試用nginx搭建websocket,參考配置 Nginx 反向代理 WebSocket长窄,先用node.js的ws模塊啟動了ws://localhost:8010滔吠,可以連接成功。但是挠日,后面使用niinx配置反向代理失敗了疮绷,連接ws://ws.repo/一直失敗,原因不明嚣潜,配置文件如下:

worker_processes  1;

error_log  logs/error.log debug;

events {
    worker_connections  1024;
}

http{
  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }

  upstream ws_server {
    #ip_hash;
    server localhost:8010;
  }

# 以下配置是在server上下文中添加冬骚,location指用于websocket連接的path。

  server {
    listen       80;
    server_name ws.repo;
    access_log /var/log/nginx/yourdomain.log;

    location / {
      proxy_pass http://192.168.198.102:8010;
      #proxy_pass http://ws_server/;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
        }
    }
}

6.參考jsmpeg官方文檔(這里,官網(wǎng)也在使用node.js來操作websocket-relay.js)

這里先npm init ws -D只冻,然后node websocket-relay ququ 9091 9092

Listening for incomming MPEG-TS Stream on http://127.0.0.1:9091/<secret>
Awaiting WebSocket connections on ws://127.0.0.1:9092/

注意看庇麦,推流要推到上面那個9091端口;而播放視頻則要用下面那個WS的9092端口∠驳拢現(xiàn)在我們拿在線測試websocket工具已經(jīng)可以連接9092了

然后就是推流操作山橄,這里參考HTML5 視頻直播(二)是看不到的,原因就是那個-f mpeg1video:

ffmpeg -re -i bjork-all-is-full-of-love.ts -codec copy
 -f mpeg1video http://127.0.0.1:9091/ququ

需要把-f mpeg1video改成-f mpegts舍悯,因?yàn)槲覀冇玫氖莟s后綴的文件啊航棱。這也是參照官網(wǎng)readme才發(fā)現(xiàn)的,另外就是demo傳的url就是ws的字符串萌衬。

<body>
    <canvas id="video-canvas"></canvas>
    <script type="text/javascript" src="jsmpeg.min.js"></script>
    <script type="text/javascript">
        var canvas = document.getElementById('video-canvas');
        //var client = new WebSocket('ws://127.0.0.1:9092');
        //var player = new JSMpeg.Player(client,
        //{canvas:canvas,loop: true, autoplay: true});
        var player = new JSMpeg.Player('ws://127.0.0.1:9092/',
        {canvas:canvas,loop: true, autoplay: true});
    </script>
</body>
六饮醇、其它

1.ffmpeg是有聲音的,雖然 HTML5 視頻直播(二)的作者寫著沒有聲音奄薇。估計(jì)是代碼庫版本有變化驳阎。另外 mpg格式也不支持,現(xiàn)在是TS格式馁蒂。參考[總結(jié)]視音頻編解碼技術(shù)零基礎(chǔ)學(xué)習(xí)方法

image.png

還有視音頻編解碼學(xué)習(xí)工程:TS封裝格式分析器

2.對比Broadway呵晚,ffmpeg是從零寫出的,可讀性好很多沫屡。
Broadway 是一個 H.264 解碼器饵隙,使用 Emscripten 工具從 Android 的 H.264 解碼器轉(zhuǎn)化而成,它還針對 WebGL 做了一些優(yōu)化沮脖。

這個解碼器支持 mp4 后綴的視頻文件金矛,有一些限制:不支持 weighted prediction for P-frames 和 CABAC entropy encoding。例如 iPhone 拍攝的視頻它就不支持勺届,可以用 FFmpeg 轉(zhuǎn)一下:

ffmpeg -i in.mp4 -vcodec libx264 -pass 1 -coder 0 -bf 0 -flags -loop -wpredp 0 out.mp4

下面是 H.264 解碼示例驶俊,視頻來自于我的 iPhone 拍攝。用閱讀器的同學(xué)請點(diǎn)到原文查看免姿。

這里還有一個長一點(diǎn)的 Demo饼酿,點(diǎn)擊查看(加載完 6M 多的 mp4 文件才開始播放,請耐心等待胚膊,流量黨慎入)故俐。

3.HTML5直播技術(shù)探究
傳統(tǒng)直播技術(shù),大多使用RTMP通過Flash進(jìn)行傳輸紊婉。隨著HTML5的逐漸實(shí)現(xiàn)药版,<video>等媒體標(biāo)簽的瀏覽器支持, 很多視頻逐漸向Html5靠攏喻犁。Youtube等視頻網(wǎng)站紛紛開始使用HTML5播放器槽片,然而縱觀當(dāng)前的直播網(wǎng)站何缓,大多還是依賴Flash。直播為何不采用HTML5呢筐乳?

目前的HTML5直播思路有以下幾種歌殃。

一是使用js調(diào)用WebGL渲染視頻乔妈,用websocket/XHR傳輸蝙云,比如jsmpeg項(xiàng)目, 實(shí)現(xiàn)了一個MPEG1的js解析器路召,該項(xiàng)目存在很多bug(今天凌晨剛剛收到j(luò)smpeg作者的github信息勃刨,說他已經(jīng)修復(fù)了好幾個我提過的bug,并且重寫了代碼)股淡,另外由于MPEG1的效能極低(比GIF好不了多少)身隐,傳輸?shù)囊曨l 質(zhì)量較差,而且js解析消耗很高CPU唯灵,這種方案不是很理想贾铝。

二是使用Native的解碼方案,使用MediaSourceExtension埠帕。比如B站開源的flv.js

4.我想在egret里面 引入第三方j(luò)smpg庫
這里有回復(fù)提供了jsmpeg的d.ts文件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垢揩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子敛瓷,更是在濱河造成了極大的恐慌叁巨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呐籽,死亡現(xiàn)場離奇詭異锋勺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)狡蝶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門庶橱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贪惹,你說我怎么就攤上這事苏章。” “怎么了馍乙?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵布近,是天一觀的道長。 經(jīng)常有香客問我丝格,道長撑瞧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任显蝌,我火速辦了婚禮预伺,結(jié)果婚禮上订咸,老公的妹妹穿的比我還像新娘。我一直安慰自己酬诀,他們只是感情好脏嚷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞒御,像睡著了一般父叙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肴裙,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天趾唱,我揣著相機(jī)與錄音,去河邊找鬼蜻懦。 笑死甜癞,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宛乃。 我是一名探鬼主播悠咱,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼征炼!你這毒婦竟也來了析既?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤柒室,失蹤者是張志新(化名)和其女友劉穎渡贾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雄右,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡空骚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了擂仍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囤屹。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逢渔,靈堂內(nèi)的尸體忽然破棺而出肋坚,到底是詐尸還是另有隱情,我是刑警寧澤肃廓,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布智厌,位于F島的核電站,受9級特大地震影響盲赊,放射性物質(zhì)發(fā)生泄漏铣鹏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一哀蘑、第九天 我趴在偏房一處隱蔽的房頂上張望诚卸。 院中可真熱鬧葵第,春花似錦、人聲如沸合溺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棠赛。三九已至哮奇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恭朗,已是汗流浹背屏镊。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工依疼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痰腮,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓律罢,卻偏偏與公主長得像膀值,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子误辑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

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

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,478評論 5 6
  • 表層習(xí)慣:早起A沧踏,早睡C,學(xué)習(xí)C 今天考試又掛了巾钉,第一次是倒庫途中停了翘狱,第二次看了左邊鏡子調(diào)平行,第三次竟然起步忘...
    高N少女閱讀 188評論 0 0
  • 很多人愛吃甜品砰苍,卻并不知道如何優(yōu)雅地品嘗甜品?每一款都有其特殊的吃法以及不同的搭配方式潦匈。那么,眾多的甜品都有哪些不...
    烘焙藝匠社閱讀 1,231評論 2 3
  • 文/徐小木 2017-04-11 清明節(jié)至今一直是雨天不停赚导, 四月份或許本就是多雨季節(jié)茬缩! 窗外的綠色...
    徐小木閱讀 305評論 2 2
  • 無緣無故負(fù)能量爆棚凰锡,每天晚上躺床上心里就麻煩的不行,找工作屢找屢碰壁圈暗,每天就和一個沒頭蒼蠅一樣亂撞掂为,撞到哪兒哪愿意...
    嗯哼北鼻康忙昂閱讀 227評論 0 0