SwarmCloud

vuePress-theme-reco SwarmCloud    2018 - 2023
P2P Streaming Engine P2P Streaming Engine

Choose mode

  • dark
  • auto
  • light
Documents
  • Introduction
  • Web SDK

    • HLS(m3u8)
    • Shaka-Player
    • Dash.js
    • MP4
    • Downloader
  • Android/AndroidTV SDK

    • v3
    • v2
  • iOS/tvOS/macOS SDK
Pricing
Contact Us
Partnership
Ecosystem
Globe
Dashboard
GitHub (opens new window)
語言
  • English
  • 中文

Documents
  • Introduction
  • Web SDK

    • HLS(m3u8)
    • Shaka-Player
    • Dash.js
    • MP4
    • Downloader
  • Android/AndroidTV SDK

    • v3
    • v2
  • iOS/tvOS/macOS SDK
Pricing
Contact Us
Partnership
Ecosystem
Globe
Dashboard
GitHub (opens new window)
語言
  • English
  • 中文
  • Introduction
  • FAQ
  • Tracking Service
  • Signaling Service
  • P2P Optimization
    • Introduction
    • Recommended m3u8 Config for live
    • Allow Http Range Request
    • Pass playback information to the SDK
  • Dashboard

  • Web HLS SDK

  • Android SDK v3

  • Android SDK v2

  • iOS/tvOS/macOS SDK

  • Flutter SDK

  • Shaka-Player SDK

  • Dash.js SDK

  • Hls.js SDK

  • Web MP4 SDK

  • Web Downloader

  • More

P2P Optimization

vuePress-theme-reco SwarmCloud    2018 - 2023

P2P Optimization


SwarmCloud

# Introduction

The performance results depend on a number of factors including time to live edge, bitrates offered, encoding profiles, ISPs served, audience geographical distribution, end-user device capacities, etc.
The configuration of m3u8(or mpd) will have a great impact on the P2P streaming. The proper configuration can significantly increase the P2P ratio. It is not recommended to use multi-bitrate m3u8/mpd.

# Recommended m3u8 Config for live

  • segment duration: 3 seconds to 4 seconds
  • number of segment in playlist: >= 10

Example for NGINX:

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

# Allow Http Range Request

Range requests are used to get only a part of a file from the server (for instance, if part of the segment has been downloaded from peer, we retrieve the other part from the CDN). By using range requests you maximize the potential of our P2P technology. Without range requests, it is not possible to take advantage of chunks of media coming from P2P and if the segment is not downloaded as a whole, this data would be considered useless. If range request is activated, we are able to get chunks of data from peer and then complete the segments by getting other chunks from the CDN, thus, reducing your CDN bandwidth. Below is an example that shows how much CDN bandwidth is saved when range requests were activated:
http-range
To activate range requests, you should enable OPTIONS requests, and range requests on both origin of your stream and CDN:

# OPTIONS REQUESTS (Required for Web)

OPTIONS requests are mandatory to be able to perform RANGE requests in a cross-domain environment.

Your server/CDN must be able to handle OPTIONS requests. Most web-servers handle it natively.

The general idea is to add the following header to the HTTP response: (only needed for web SDK)

Access-Control-Allow-Methods: GET, OPTIONS

# RANGE REQUESTS

The general idea is to add the following header to the HTTP response:

Access-Control-Allow-Headers: Range

# Example for 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;
}

# Example for NIMBLE

Open your config file (Usually located at /etc/nimble/nimble.conf), add the following lines at the bottom of the file:

access_control_allow_origin = *
access_control_expose_headers = Content-Length
access_control_allow_headers = Range

Save the file and restart the nimble service using this command: sudo service nimble restart

# Pass playback information to the SDK

SwarmCloud uses local proxy server to perform p2p, so player playing information cannot be obtained by SDK. It is recommended to pass the time interval from the current playing time to the buffer front to the SDK through the API provided by the SDK.

# Android ExoPlayer

import com.cdnbye.core.p2p.PlayerInteractor;
P2pEngine.getInstance().setPlayerInteractor(new PlayerInteractor() {
    public long onBufferedDuration() {
        // Exoplayer in milliseconds
        if (play != null) {
            return player.getBufferedPosition() - player.getCurrentPosition();
        }
        return -1;
    }
});

# 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;         // Time Unit: second
            break;
        }
    }
    return bufferedDuration;
}