SwarmCloud

vuePress-theme-reco SwarmCloud    2018 - 2022
P2P流媒體引擎 P2P流媒體引擎

Choose mode

  • dark
  • auto
  • light
線上文檔
  • 快速入門
  • Web SDK

    • HLS
    • dash.js
    • Shaka-Player
    • MP4
    • 大文件下載
  • 安卓/安卓TV SDK

    • v2 (Java)
    • v3 (Kotlin, beta)
  • iOS/tvOS/macOS SDK
定價
關於我們
生態
實時地球
管理面板
GitHub (opens new window)
language
  • English
  • 中文

線上文檔
  • 快速入門
  • Web SDK

    • HLS
    • dash.js
    • Shaka-Player
    • MP4
    • 大文件下載
  • 安卓/安卓TV SDK

    • v2 (Java)
    • v3 (Kotlin, beta)
  • iOS/tvOS/macOS SDK
定價
關於我們
生態
實時地球
管理面板
GitHub (opens new window)
language
  • English
  • 中文
  • 快速入門
  • 常見問題
  • Tracker服務
  • 信令服務
  • P2P優化
    • 簡介
    • 直播模式m3u8/mpd參考配置
    • 允許Http Range請求
    • 將播放緩沖信息回調給SDK
  • 控製臺

  • HLS Double Engine

  • 安卓 SDK v2

  • 安卓 SDK v3

  • iOS/tvOS/macOS SDK

  • Flutter SDK

  • Hls.js SDK

  • HLS via ServiceWorker

  • Shaka-Player SDK

  • Web MP4 SDK

  • Dash.js SDK

  • 大文件下載 SDK

  • 更多

P2P優化

vuePress-theme-reco SwarmCloud    2018 - 2022

P2P優化


SwarmCloud

# 簡介

m3u8的配置(或者mpd)對P2P效果會產生很大的影響,適當的配置(包括每個切片的時長和每個m3u8/mpd包含的切片數量等)可以顯著提高P2P率。建議不要使用多碼率m3u8/mpd。

# 直播模式m3u8/mpd參考配置

  • 切片時長:3到4秒
  • 每個m3u8/mpd切片數量:不少於10個

以NGINX為例:

rtmp {
    server {
        ...
        application show {
            ...
            hls_fragment 4;                # 4 seconds fragments
            hls_playlist_length 60;        # 60 seconds playlist
        }
    }
}

# 允許Http Range請求

Http Range請求用於下載指定範圍的數據,可以在一部分數據已用P2P下載的情況下,剩余部分用http下載補足。如果從對等端P2P下載速度較慢,那麽在達到超時時間後,就可以把剩余數據交給http range請求下載,而不需要重新完整下載整個數據,從而節省CDN的帶寬,下圖闡述了不采用和采用Http Range的區別:
http-range
要啟動Http Range請求,需要同時在源伺服器和CDN開啟OPTIONS和RANGE請求:(Native端不需要開啟OPTIONS)

# OPTIONS請求

OPTIONS請求是瀏覽器在跨域情況下發起Range請求之前的預檢請求,一般只需要配置伺服器使Http頭有以下響應:(安卓和iOS不需要配置)

Access-Control-Allow-Methods: GET, OPTIONS

# RANGE請求

要開啟RANGE請求,一般只需要配置伺服器使Http頭有以下響應:

Access-Control-Allow-Headers: Range

# NGINX 示例

add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
add_header 'Access-Control-Allow-Headers' 'Range';
add_header 'Access-Control-Allow-Origin' '*';
add_header Accept-Ranges bytes;
# allow CORS preflight requests
if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Headers' 'Range';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
}

# 將播放緩沖信息回調給SDK

由於P2P采用本地代理伺服器模式,SDK與播放器解耦,無法獲取播放器的播放信息。建議在直播或者MP4播放模式下,通過SDK提供的接口 ,將播放器從當前播放時間到緩沖前沿的時間間隔回調給SDK。

# 安卓ExoPlayer示例

import com.cdnbye.core.p2p.PlayerInteractor;
P2pEngine.getInstance().setPlayerInteractor(new PlayerInteractor() {
    @Override
    public long onBufferedDuration() {
        // Exoplayer 單位:毫秒
        return player.getBufferedPosition() - player.getCurrentPosition();
    }
});

# iOS AVPlayer示例

@interface ViewController () <CBP2pEngineDelegate>
...
[CBP2pEngine sharedInstance].delegate = self;
NSURL *parsedUrl = [[CBP2pEngine sharedInstance] parseStreamURL:ORIGINAL_URL];
AVPlayerItem *playerItem =[[AVPlayerItem alloc] initWithURL: parsedUrl];
self.player = [[AVPlayer alloc] initWithPlayerItem: playerItem];
...
#pragma mark - **************** CBP2pEngineDelegate ****************
-(NSTimeInterval)bufferedDuration {
    NSTimeInterval currentTime = CMTimeGetSeconds([self.player currentTime]);
    NSTimeInterval bufferedDuration = 0;
    for (NSValue *value in [[self.player currentItem] loadedTimeRanges]) {
        CMTimeRange timeRange = [value CMTimeRangeValue];
        NSTimeInterval start = CMTimeGetSeconds(timeRange.start);
        NSTimeInterval end = start + CMTimeGetSeconds(timeRange.duration);
        if (currentTime >= start && currentTime <= end) {
            bufferedDuration = end - currentTime;         // 單位:秒
            break;
        }
    }
    return bufferedDuration;
}