Skip to content

P2pEngineHls API

var engine = new P2pEngineHls(p2pConfig);

實例化 P2pEngineHls

如果指定了 p2pConfig,那麼對應的預設值將會被覆蓋。

欄位型別預設值描述
hlsjsInstanceHlsjsnullHlsjs的實例化物件,如果沒有傳入則不會啟用基於 Hlsjs 的引擎。
proxyOnlybooleanfalse是否強制啟用基於 ServiceWorker 的引擎。
logLevelstring|boolean'error'log的等級,分為'warn'、'error'、'none',設為true等於'warn',設為false等於'none'。
tokenstringundefinedtoken用於控制台多網域資料彙總展示,另外如果自訂channelId也需要設定token。
livebooleantrue設定直播或隨選模式,不同模式會自動設定不同的hls.js參數。
announcestring'https://cn.cdnbye.com/v1'tracker伺服器位址。
trackerZonestring'eu'tracker伺服器位址的國家代號,分為'cn'、'eu'、'hk'、'us'。
memoryCacheLimitObject{"pc": 400 * 1024 * 1024, "mobile": 100 * 1024 * 1024}記憶體快取的最大資料量,分為PC和mobile。
p2pEnabledbooleantrue是否開啟P2P。
webRTCConfigObject{}用於設定stun和datachannel的字典
useHttpRangebooleantrue在可能的情況下使用Http Range請求來補足p2p下載逾時的剩餘部分資料。
sharePlaylistbooleanfalse是否允許m3u8檔案的P2P傳輸。
strictSegmentIdbooleanfalse使用基於url的SegmentId,替代預設基於序號的。
swAutoRegisterbooleantrue是否在初始化基於 ServiceWorker 的引擎後自動註冊 ServiceWorker 。
swFilestring'./sw.js'ServiceWorker檔名和路徑。
swScopestring'./'ServiceWorker預設作用域是目前目錄以及所有子目錄,因此如果將 sw.js 放在網站根目錄,那麼所有網站請求都在 ServiceWorker 控制範圍內。
mediaElemHTMLMediaElement|stringundefined指定media標籤的id或Element物件,預設是document中的第一個video或audio元素。
useDiskCachebooleantrue隨選模式用 IndexedDB 儲存資料。
diskCacheLimitObject{"pc": 1500 * 1024 * 1024, "mobile": 1000 * 1024 * 1024}磁碟快取的最大資料量,分為PC和mobile。
prefetchOnlybooleanfalse只採用預先載入的方式進行P2P下載。
startFromSegmentOffsetnumber3開始請求tracker服務的segment偏移量。

P2pEngineHls 屬性和方法

P2pEngineHls.version (static)

取得 SDK 的版本號。

P2pEngineHls.protocolVersion (static)

取得 P2P 協定的版本號,與其他平台互通的前提是 P2P 協定版本號相同。

P2pEngineHls.HlsjsEngine (static)

取得基於 Hlsjs 的 P2pEngine 的建構函式。

P2pEngineHls.ServiceWorkerEngine (static)

取得基於 ServiceWorker 的 P2pEngine 的建構函式。

P2pEngineHls.tryRegisterServiceWorker(config) (static)

用於註冊 ServiceWorker 的靜態方法,如果指定了 config,那麼對應的預設值將會被覆蓋。

欄位型別預設值描述
swFilestring'./sw.js'ServiceWorker檔名和路徑。
swScopestring'./'ServiceWorker預設作用域是目前目錄以及所有子目錄。

P2pEngineHls.getBrowser() (static)

取得瀏覽器的名稱,可能取值如下:

  • Chrome
  • Firefox
  • Mac-Safari
  • iOS-Safari
  • X5
  • Unknown

P2pEngineHls.isSupported() (static method)

判斷目前瀏覽器是否支援WebRTC data channel,以及 MSE 或者 SeviceWorker 其中之一。

P2pEngineHls.isMSESupported() (static)

判斷目前瀏覽器是否支援 MEDIA SOURCE EXTENSIONS 。

P2pEngineHls.isServiceWorkerSupported() (static)

判斷目前瀏覽器是否支援 ServiceWorker 。

engine.realEngine

取得目前啟用的內部引擎實例。

engine.engineName

取得目前啟用的內部引擎的名稱,可能取值如下:

  • HlsjsP2pEngine
  • HlsSwP2pEngine

engine.enableP2P()

在p2p暫停或未啟動情況下啟動p2p。

engine.disableP2P()

停止p2p並釋放記憶體。

engine.destroy()

停止p2p、銷毀engine並釋放記憶體。在Hls.js銷毀時會自動呼叫。

engine.registerServiceWorker()

註冊 ServiceWorker 並回傳一個 promise 。

engine.unregisterServiceWorker()

銷毀 ServiceWorker 並回傳一個 promise 。

P2pEngineHls事件

engine.on('peerId', function (peerId) {})

當從伺服器端取得peerId時回呼該事件。

engine.on('peers', function (peers) {})

當與新的節點成功建立p2p連線時回呼該事件。

engine.on('stats', function (stats) {})

該回呼函式可以取得p2p資訊,包括:
stats.totalHTTPDownloaded: 從HTTP(CDN)下載的資料量(單位KB)
stats.totalP2PDownloaded: 從P2P下載的資料量(單位KB)
stats.totalP2PUploaded: P2P上傳的資料量(單位KB)
stats.p2pDownloadSpeed: P2P下載速度(單位KB/s)

engine.on('serverConnected', function (connected) {})

當連線/中斷websocket時回呼該事件。

engine.on('exception', function (e) {})

該回呼函式可以取得SDK的異常資訊,包括:
e.code: 異常識別碼(TRACKER_EXPT SIGNAL_EXPT HLSJS_EXPT)
e.message: 異常資訊
e.stack: 異常堆疊資訊

透過p2pConfig取得p2p資訊

javascript
p2pConfig: {
    getStats: function (totalP2PDownloaded, totalP2PUploaded, totalHTTPDownloaded, p2pDownloadSpeed) {
        // 取得p2p下載資訊
    },
    getPeerId: function (peerId) {
        // 取得本節點的Id
    },
    getPeersInfo: function (peers) {
        // 取得成功連線的節點的資訊
    },
    onHttpDownloaded: function (traffic) {
        // 監聽http下載流量
    },
    onP2pDownloaded: function (traffic, speed) {
        // 監聽p2p下載流量和速度
    },
    onP2pUploaded: function (traffic) {
        // 監聽p2p上傳流量
    },
}

WARNING

下載和上傳資料量的單位是KB,下載速度的單位是KB/s。

在Hls.js新增的API

Hls.engineVersion (static method)

目前外掛程式的版本號

Hls.WEBRTC_SUPPORT (static method)

判斷目前瀏覽器是否支援WebRTC

javascript
if (Hls.WEBRTC_SUPPORT) {
  // WebRTC is supported
} else {
  // Use a fallback
}

Hls.P2pEngine (static method)

從Hls取得 P2pEngine,等價於直接引入的 P2pEngineHls

實例化與參數設定

var hls = new Hls({p2pConfig: [opts]});

建立一個新的Hls實例。其中 p2pConfig 等價於傳入 P2pEngineHls 的 p2pConfig,此時無需再指定 hlsjsInstance

hls.p2pEngine

Hls 實例中取得 P2pEngineHls 實例。

HlsProxy API

new HlsProxy(config);

建立一個 HlsProxy 實例。

如果指定了 config,那麼對應的預設值將會被覆蓋。

欄位型別預設值描述
httpHeadersForPlaylistfunction(url, headers)null設定m3u8請求的自訂http標頭,如:httpHeadersForPlaylist: (url, headers) => { headers.set('token', 'xxx') }
httpHeadersForMediaFilefunction(url, headers)null設定ts請求的自訂http標頭,如:httpHeadersForMediaFile: (url, headers) => { headers.set('token', 'xxx') }
insertTimeOffsetTagbooleanfalse僅在直播模式生效,在m3u8檔案中插入 "#EXT-X-START:TIME-OFFSET=[playlistTimeOffset]",強制播放器從某個位置開始載入
playlistTimeOffsetnumber0.01僅在insertTimeOffsetTag=true時生效,如果為負則從播放清單結尾往前偏移(單位:秒)
allowedMediaFilesArray['ts', 'mp4', 'm4s', 'fmp4']需要支援的媒體檔案副檔名,如 ['txt', 'png'],如果無副檔名,可以設定 ['*']
mediaFileSeparatorString'.'媒體檔案副檔名分隔符
allowedPlaylistSuffixArray['m3u8']需要支援的額外播放清單檔案副檔名,如 ['txt']

HlsProxy.version (static)

取得 HlsProxy 的版本號。

進階用法

解決動態m3u8路徑問題

某些串流媒體提供商的m3u8是動態產生的,不同節點的m3u8位址不一樣,例如example.com/clientId1/streamId.m3u8和example.com/clientId2/streamId.m3u8,而本外掛程式預設使用m3u8位址(去掉查詢參數)作為channelId。這時候就要建構一個共同的channelId,使實際觀看同一直播/影片的節點處在相同頻道中。

javascript
// 必須先在 p2pConfig 設定 token,才能自訂 channelId ! 與其他平台互通需要相同的 token 和 channelId 。
p2pConfig: {
    token: YOUR_TOKEN,
    channelId: function (m3u8Url) {
        const videoId = extractVideoIdFromUrl(m3u8Url);   // 忽略差異部分,建構一個一致的channelId,其中 extractVideoIdFromUrl 需要自己定義,可以擷取url中的影片ID作為結果回傳
        return videoId;
    }
    // channelId: VIDEO_ID       // for fixed channel id
}

http://example.com/token123456/video1/playlist.m3u8 來舉例,其中 token123456 是根據不同使用者產生的token,video1 是影片的唯一ID。

javascript
p2pConfig: {
    token: YOUR_TOKEN,
    channelId: function (m3u8Url) {
        var parts = m3u8Url.split('/');
        var videoId = parts[parts.length-2]+'/'+parts[parts.length-1];
        return videoId;
    }
}

按如上設定後,結果如下,token被去掉,只保留video ID:

<!-- URL to be replaced -->
http://example.com/token123456/video1/playlist.m3u8

<!-- Resulting channelId -->
video1/playlist.m3u8

WARNING

如果要與其他平台互通,則必須確保兩者擁有相同的 token 和 channelId 。

允許Http Range請求

當對等端上行頻寬不夠時,可能導致p2p傳輸逾時而轉向http下載,原本p2p下載的資料無法複用。Http Range請求用於補足p2p下載逾時的剩餘部分資料,要開啟Http Range,首先需要來源伺服器支援,請參考允許Http Range請求,然後增加以下設定:

javascript
p2pConfig: {
    useHttpRange: true,
}

排除某些特殊的切片檔案

某些情況下我們不想讓某些切片檔案參與P2P,比如SSAI(Server Side Ad Insertion)產生的特定於使用者的切片,這個時候可以利用 segmentBypass 這個函式來進行過濾:

javascript
p2pConfig: {
    segmentBypass: (url, tags) => {
        return isSSAISegment(url)
    },
}

在 sw.js 設定播放時間偏移量

透過在m3u8設定一個特殊的tag,可以強制播放器從清單開始位置載入,從而提升P2P效果,但同時會增加延遲,需要權衡考慮。

javascript
// sw.js
self.importScripts('https://cdn.jsdmirror.com/npm/@swarmcloud/hls/hls-proxy.js')
new HlsProxy({
    insertTimeOffsetTag: true,
    playlistTimeOffset: 0.01,
})

如何在 Service Worker 模式下支援更多檔案副檔名?

sw.js預設支援的 playlist 副檔名是 m3u8,預設支援的媒體檔案副檔名是 'ts', 'mp4', 'm4s', 'fmp4',如果需要支援更多副檔名,可以自訂設定:

javascript
self.importScripts('https://cdn.jsdmirror.com/npm/@swarmcloud/hls/hls-proxy.js')
new HlsProxy({
    allowedPlaylistSuffix: ['m3u8', 'html'],     // 如果需要支援的播放清單 url 是 xxx.html
    allowedMediaFiles: ['ts', 'mp4', 'm4s', 'fmp4', 'jpg'], // 如果需要支援的媒體檔案 url 是 xxx.jpg
    // allowedMediaFiles: ['*']   // 如果沒有副檔名
})

自行設定 STUN 和 TURN 伺服器位址

STUN用於p2p連線過程中取得公用網路IP位址,TURN則可以在p2p連線不通時用於中繼資料。本SDK已內建公開的STUN服務,開發者可以透過P2pConfig來更換STUN位址。TURN伺服器則需要開發者自行架設,可以參考coturn

javascript
p2pConfig: {
    webRTCConfig: {
       iceServers: [
           { urls: YOUR_STUN_OR_TURN_SERVER }
       ]
    }
}

切片Hash校驗

有時候我們需要校驗從節點下載的切片的合法性(類似bittorrent的雜湊校驗)。 SDK提供了一個鉤子函式,可以回呼下載的切片供開發者進行校驗。用於校驗的 雜湊表建議直接從伺服器下載,開發者可以透過程式計算每個ts檔案的雜湊並儲存於 特定的檔案中或直接嵌入到m3u8檔案中。如果校驗失敗,直接在回呼函式中 回傳false即可。

javascript
p2pConfig: {
   validateSegment: function (segId, buffer) {
       var hash = hashFile.getHash(segId);
       return hash === md5(buffer);
   }
}

粤ICP备18075581号