1. 程式人生 > >HTML5 視訊直播(二)

HTML5 視訊直播(二)

提醒:本文最後更新於 1355 天前,文中所描述的資訊可能已發生改變,請謹慎使用。

上篇部落格中,我介紹了目前移動端唯一可行的 HTML5 直播方案:HLS。實際上,HLS 除了上回提到過的延遲很大這個缺點之外,在 iOS 的 Safari 瀏覽器中還只能全屏播放,也無法做到自動播放,這個是 iOS 系統對 Video 標籤統一做的限制。有沒有什麼辦法解決這些問題呢?

我們換個思路,既然原生 Video 有這樣那樣的問題,不如直接拋棄它。利用 Web Sockets 實現視訊流的實時傳輸,使用純 JS 進行視訊解碼,再用 Canvas 逐幀畫出影象,這不就實現了直播麼。當我有個這個想法之後,初步覺得可行,立馬開始一番搜尋,收穫頗豐。

本文要用到的 Web Sockets 在移動端支援度如下表:

瀏覽器 支援新標準的版本
iOS Safari 6.1+
Android Browser(Webview) 4.4+
Chrome for Android 42+

另外,轉換視訊格式、生成視訊流還需要用到一個神器:FFmpeg

Mac 下最簡單的做法是通過 Homebrew 安裝,直接 brew install ffmpeg 就可以了。

Ubuntu 下可以先新增這個源:

sudo add-apt-repository ppa:mc3man/trusty-media

sudo apt-get install ffmpeg

,也能輕鬆搞定。

Decoder in JavaScript

純 JS 實現的視訊解碼器我找到了兩個可用的:Broadwayjsmpeg

是一個 H.264 解碼器,使用 Emscripten 工具從 Android 的 H.264 解碼器轉化而成,它還針對 WebGL 做了一些優化。

這個解碼器支援 mp4 字尾的視訊檔案,有一些限制:不支援 weighted prediction for P-frames 和 CABAC entropy encoding。例如 iPhone 拍攝的視訊它就不支援,可以用 FFmpeg 轉一下:

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

下面是 H.264 解碼示例,視訊來自於我的 iPhone 拍攝。用閱讀器的同學請點到原文檢視。

這裡還有一個長一點的 Demo,點選檢視(載入完 6M 多的 mp4 檔案才開始播放,請耐心等待,流量黨慎入)。

則是一個 MPEG1 解碼器,它是由作者從零編寫出來的,並不像 Broadway 那樣是從其他語言翻譯而成,所以程式碼可讀性要好很多,程式碼也更輕量級。

jsmpeg 也對視訊檔案編碼方式有一些要求:不支援 B-Frames,視訊寬度必須是 2 的倍數。還是可以用 FFmpeg 來轉換:

ffmpeg -i in.mp4 -f mpeg1video -vf "crop=iw-mod(iw\,2):ih-mod(ih\,2)" -b 0 out.mpg

下面是 MPEG1 解碼示例,視訊來自於網上。用閱讀器的同學請點到原文檢視。

這裡也有一個長一點的 Demo,點選檢視(載入完 3M 多的 mpg 檔案才開始播放。其實沒什麼好看的,內容跟上面一樣,編碼格式不同而已)。

Live Streaming

看到這裡,大家肯定會說,這不是要一次性下完全部內容麼,怎能稱之為直播。是的,要實現直播,還要用 Web Sockets 實現一個實時傳輸流的服務。FFmpeg 支援很多直播流格式,但不支援 Web Sockets。解決方案是用 FFmpeg 開一個 HTTP 直播流,再開個 Node 服務轉一下。

詳細一點的過程是這樣的,用 NodeJS 監聽 FFmpeg 的 HTTP 直播地址,把收到的資料 通過 Web Sockets 廣播給所有客戶端。核心程式碼就是下面這幾行:

//HTTP Server to accept incomming MPEG Stream
var streamServer = require('http').createServer( function(request, response) {
    request.on('data', function(data){
        socketServer.broadcast(data, {binary:true});
    });
}).listen(STREAM_PORT);

這段程式碼來自於上面介紹的 jsmpeg 專案,完整程式碼在這裡。啟動這個服務試試(需先裝好 ws 模組):

node ~/live/stream-server.js ququ 9091 9092

三個引數分別是服務標識、HTTP 埠、WS 埠。啟動後,螢幕上會顯示兩個地址:

Listening for MPEG Stream on http://127.0.0.1:9091/<secret>/<width>/<height>
Awaiting WebSocket connections on ws://127.0.0.1:9092/

好了,現在就可以使用 FFmpeg 來推送 HTTP 視訊流了:

ffmpeg -re -i fox.mpg -codec copy -f mpeg1video https://qgy18.com:9091/ququ/640/360

-re 引數表示以視訊實際播放速率解碼,不加這個引數一般會導致直播速率變得飛快。ququ 是啟動 Node 服務時指定的標識,可以做個簡單校驗,避免 Node 轉發不認識的流。最後的 640360 是視訊的寬高,可以根據實際情況指定。

最後,稍微改一下前面的 Demo,讓 jsmpeg 從 WS 流中獲取資料就可以實現直播了:

var canvas = document.getElementById('videoCanvas');
var client = new WebSocket('ws://qgy18.qgy18.com:9092/');
var player = new jsmpeg(client, {canvas:canvas, autoplay: true});

Capture Webcam

上面演示的是從檔案中獲取視訊流進行直播,如果把資料來源換成攝像頭也很容易。FFmpeg 官方 wiki 上有在 Windows / MacOS / Linux 下讀取攝像頭的詳細指南。

以 Mac 為例,它支援 AVFoundation 和 QTKit 兩種不同的技術讀取攝像頭,在比較新的系統(10.7+)上,推薦使用 AVFoundation,QTKit 後續可能會被廢棄。

我的 Mac 系統是最新的,直接使用 AVFoundation。首先檢視可用攝像頭列表:

ffmpeg -f avfoundation -list_devices true -i ""

[AVFoundation input device @ 0x7fdd53c228c0] AVFoundation video devices:
[AVFoundation input device @ 0x7fdd53c228c0] [0] FaceTime HD Camera
[AVFoundation input device @ 0x7fdd53c228c0] [1] Capture screen 0
[AVFoundation input device @ 0x7fdd53c228c0] AVFoundation audio devices:
[AVFoundation input device @ 0x7fdd53c228c0] [0] Built-in Microphone

可以看到,編號為 0 的 video 裝置正是我想要的攝像頭(編號為 1 的裝置是電腦螢幕,直播螢幕也挺好玩),下面這行命令就可以捕捉它,並把視訊流推到之前的 Node 服務上:

ffmpeg -f avfoundation -framerate 30 -i "0" -f mpeg1video -b 500k -r 20 -vf scale=640:360 https://qgy18.com:9091/ququ/640/360

-b-r 分別用來指定位元速率和幀率,可以根據實際情況調整。這樣,我攝像頭拍攝到的畫面,就被 FFMpeg 捕捉下來實時推給遠端 Node 服務,實時轉化成 WS 資料流,廣播給所有終端播放。雖然過程很曲折,但是基本上看不到延遲,體驗還是很不錯的。

最後,說幾個問題:

  • 首先,最大的問題是:這種方案只實現了 Canvas 渲染畫面部分,無法支援聲音(沒聲音還好意思叫直播,摔!!!);
  • 其次,JS 解碼能力還是稍微有點弱,最後的示例中我有意指定 scale 引數縮小了畫面,但在 iPhone 6 Plus 非自帶瀏覽器中還會卡(iOS 第三方 APP 趕緊放棄老系統,果斷的把 WKWebView 用起來吧~~~);
  • 第三,好像略微有點蛋疼(好,這次就寫這麼多,收工。。。);

--EOF--

提醒:本文最後更新於 1355 天前,文中所描述的資訊可能已發生改變,請謹慎使用。

相關推薦

HTML5 視訊直播

提醒:本文最後更新於 1355 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 上篇部落格中,我介紹了目前移動端唯一可行的 HTML5 直播方案:HLS。實際上,HLS 除了上回提到過的延遲很大這個缺點之外,在 iOS 的 Safari 瀏覽器中還只能全屏播放,也無法做到自動播放,這個是 i

HTML5 視訊直播

提醒:本文最後更新於 1349 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 連續寫了兩篇有關視訊直播的文章之後,有同學問我為什麼沒有 WebRTC 相關內容。實際上一開始我就說過,我的需求是在移動 WEB 端上直播視訊,而移動端瀏覽器現階段對「WebRTC 的支援度」非常不樂觀,所以我就

HTML5 視訊直播

提醒:本文最後更新於 776 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 前不久工作中遇到了在移動 WEB 端直播視訊的需求,研究了一下相關技術,記錄一下。 目前 WEB 上主流的視訊直播方案有 HLS 和 RTMP,移動 WEB 端目前就只有 HLS 能用,我們重點介紹它。 upda

HTML5學習筆記視訊與音訊處理

一、<video>  1、<video>是H5的新標籤,用來處理視訊,在此之前,各網站用來處理視訊一直使用flash技術     flash的缺點有以下幾方面,首先原生瀏覽器原生不支援,需要外掛,其次過多的使用會導致網站效能變差,最後就是

web前端基礎教學視訊分享html5+css3基礎教學

與卿再世相逢日,玉樹臨風一少年 夜未深,夢未成,怎敢睡去。 【寫在前面】 前端一入深似海,從此黑絲漸發白。 孤燈下,執一本。 程式設計不易,且行且放棄? 【分享與你】(百度雲盤永久有效) 連結:https://pan.baidu.com/s/1gr66gQawvgRSKjQQoO4GDQ

iOS直播GPUImage音視訊採集

GPUImage是一個開源的基於GPU的第三方影象處理庫,可以對影象進行美化、新增各種濾鏡等。GPUImage的視訊採集部分的原始碼,也是和上文中的AVFoundation實現採集(https://blog.csdn.net/dolacmeng/article/

HTML5基礎小結——標簽小例

加速 支持 ide oat enter controls 畫圓 side tint 隨篇博客的思維導圖。繼續: 二。看下標簽的使用,這裏看幾個小樣例(效果圖不再給出): 1。結構標簽的使用,這裏來看一個頁面的布局:<!doc

HTML5的學習HTML5標籤

3.按功能排列標籤 (注:紅色為HTML5不支援的,藍色為HTML5新增的標籤元素。)   3.1基本 標籤 描述 HTML4 HTML5 <!--...--> 定義註釋。

資料庫視訊總結——增刪改查

查: 簡單的SELECT語句: 例如: select student_Name,student_Sex from student_Info 1、可以當做計算機來使用: select 12*13 as 計算結果 2、讓列名發生變化: Select 原來的列名 as 新的列

即時通訊音視訊開發視訊編解碼之數字視訊介紹

前言 即時通訊應用中的實時音視訊技術,幾乎是IM開發中的最後一道高牆。原因在於:實時音視訊技術 = 音視訊處理技術 + 網路傳輸技術 的橫向技術應用集合體,而公共網際網路不是為了實時通訊設計的。 系列文章 本文是系列文章中的第2篇,本系列文章的大綱如下:   《即時

數字視訊基礎

轉自https://blog.csdn.net/shanghaiqianlun/article/details/26484771   2.    常用數字視訊標準 2.1 BT656     

零基礎實現攝像頭的全平臺直播 公網直播的實現

接上回,我們實現內網直播,可以實現直播的web觀看,該篇博文我們將實現公網的直播。 由於通用最多都是 window系統,我們的軟體也是可以在Windows上執行,我們後面就以window為例進行操作 下載穿透軟體 下載地址:https://natapp.cn/#do

golang 流量統計系統視訊總結

總體流程 解析使用者訪問行為日誌部分 程式碼實現: package main import ( "bufio" "crypto/md5" "encoding/hex" "flag" "github.com/mediocregopher/radix.v2/p

HTML5 基礎知識

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <title></title> </head

[持續更新]HTML5學習筆記

1.  元素分類 元資料元素(metadata element):由此可見主要是<meta>元素中的事情了,向瀏覽器提供資訊和指示; 流元素(flow element):聽名字怪異,但是其實是規定這些元素可以成為父元素; 短語元素(phrasing elemen

Native和html5的互動Android native傳資料給js

js裡面 某函式用來接收android傳過來的資料 function onDeviceScanResult(data) { alert("Device Scan Result:" + data); } Android裡面把資料拼接成字串發給js ta); }W

iOS音視訊專欄WebRTC音訊模組在iOS上的應用

公司的專案是通過WebRTC的APM(Audio Processing Module)模組進行的聲音處理(降噪,增益,回聲消除等),通過呼叫audio_device獲取裝置音訊硬體。整套音訊處理都是

Intel智慧工業相機功能視訊演示

更多精彩內容,請微信搜尋“FPGAer俱樂部”關注我們。 Intel推出工業智慧相機方案 APOLLO ISLAND,該相機硬體系統如下圖所示,CPU採用Intel ATOM x5 E3930,FPGA採用CycloneV GT 5CGTFD7D5F27C7N, Senso

從Android原生角度看移動html5開發APP之整體mui初始化

有幾天沒有寫用html5開發移動app的總結了,今天抽出點時間來總結一下吧。 不多說直接入主題: 1、html就是一個框架,雖然說有點想layout,但是還是有點不一樣的,具體的就是一個是標籤,一個是具體控制元件。在移動開發中html用的最多的就是塊標籤即<div&g

Android實現錄屏直播需求才是硬道理之產品功能調研

前面的Android實現錄屏直播(一)ScreenRecorder的簡單分析一文中我們對 ScreenRecorder 這個開源 Demo 中的實現機制大概有了瞭解,但在繼續寫這個系列文章的時候發現每一個細節都太緊密了,稍微不注意就會深入每個知識