API & Config
# P2P Configuration
Create CBP2pConfig instance.
CBP2pConfig *config = [CBP2pConfig defaultConfiguration];
let config = CBP2pConfig.defaultConfiguration()
The default fields (shown below) can be overridden.
Field | Type | Default | Description |
---|---|---|---|
logLevel | CBLogLevel | CBLogLevelWarn | Print log level(CBLogLevelNone, CBLogLevelDebug, CBLogLevelInfo, CBLogLevelWarn, CBLogLevelError). |
webRTCConfig | RTCConfiguration | - | Providing options to configure WebRTC connections. |
announce | NSString | @"https://tracker.cdnbye.com/v1" | The address of tracker server. |
wsSignalerAddr | NSString | @"wss://signal.cdnbye.com" | The address of signal server. |
diskCacheLimit | NSUInteger | 1024 * 1024 * 1024 | The max size of binary data that can be stored in the cache for VOD(Set to 0 will disable disk cache). |
memoryCacheLimit | NSUInteger | 100 * 1024 * 1024 | The max size of binary data that can be stored in the memory cache. |
p2pEnabled | BOOL | YES | Enable or disable p2p engine. |
wifiOnly | BOOL | NO | Only allow uploading on Wi-Fi. |
localPort | NSUInteger | 0 | The port for local http server(default is random port). |
downloadTimeout | NSTimeInterval | 10.0 | TS file download timeout by HTTP. |
dcDownloadTimeout | NSTimeInterval | 15.0 | Max download timeout for WebRTC datachannel. |
tag | NSString | @"unknown" | User defined tag which is presented in console. |
maxPeerConnections | NSUInteger | 12 | Max peer connections at the same time. |
useHttpRange | BOOL | YES | Use HTTP ranges requests where it is possible. Allows to continue (and not start over) aborted P2P downloads over HTTP. |
httpHeaders | NSMutableDictionary | nil | Set http headers while requesting ts and m3u8. |
channelIdPrefix | NSString | nil | Required while using customized channelId(5 < length < 15), recommended to set it as the unique identifier of your organization. |
# P2P Engine
Initialize CBP2pEngine in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CBP2pConfig *config = [CBP2pConfig defaultConfiguration];
[[CBP2pEngine sharedInstance] startWithToken:YOUR_TOKEN andP2pConfig:config];
return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = CBP2pConfig.defaultConfiguration()
CBP2pEngine.sharedInstance().start(token: YOUR_TOKEN, p2pConfig: config)
return true
}
Where token is your Customer ID, please replace it by your own token obtained from console. Get parsed local stream url by passing the original stream url(m3u8) to CBP2pEngine instance:
NSURL *parsedUrl = [[CBP2pEngine sharedInstance] parseStreamURL:ORIGINAL_URL];
let parsedUrl = CBP2pEngine.sharedInstance().parse(streamURL: ORIGINAL_URL)
# Switch Stream URL
When Switching to a new stream URL, before passing new stream url(m3u8) to the player, pass that URL through CBP2pEngine instance:
NSURL *newParsedURL = [[CBP2pEngine sharedInstance] parseStreamURL:NEW_ORIGINAL_URL];
let newParsedURL = CBP2pEngine.sharedInstance().parse(streamURL: NEW_ORIGINAL_URL)
# P2P Statistics
Add a observer to observe downloading statistics:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMsg:) name:kP2pEngineDidReceiveStatistics object:nil];
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveMsg), name: NSNotification.Name(rawValue: kP2pEngineDidReceiveStatistics), object: nil)
Then get the downloading statistics, including p2pDownloaded, p2pUploaded, httpDownloaded, peers and serverConnected from dictionary:
- (void)didReceiveMsg:(NSNotification *)note {
NSDictionary *dict = (NSDictionary *)note.object;
NSLog(@"didReceiveMsg %@", dict);
}
@objc func didReceiveMsg(note:NSNotification) {
}
PS: The unit of download and upload is KB.
# Advanced Usage
# Improve Live Streaming Performance
On Live streaming, to improve performance, we recommend to tell p2p engine the duration from the playback time to the end of the buffered interval. In order to do so, you need to implement CBP2pEngineDelegate .
@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; // In seconds
break;
}
}
return bufferedDuration;
}
# Dynamic m3u8 Path Issue
The channelId is an identifier used by our backend to match peers that are watching the same content. It is an optional parameter, and by default, we generate channelId from the content URL by removing any query parameters and protocol from it. Some m3u8 urls play the same live/vod but have different paths on them. For example, example.com/clientId1/streamId.m3u8 and example.com/clientId2/streamId.m3u8. In this case, you can format a common channelId for them.
- For SDK version >= 1.10
// Set channelIdPrefix in p2pConfig before setting channelId! Connectivity with other platform should have the same channelIdPrefix.
CBP2pConfig *config = [CBP2pConfig defaultConfiguration];
config.channelIdPrefix = YOUR_UNIQUE_ID;
[[CBP2pEngine sharedInstance] startWithToken:YOUR_TOKEN andP2pConfig:config];
// If ts address in m3u8 is relative, you need to set the segmentid
[CBP2pEngine sharedInstance].segmentId = ^NSString * _Nonnull(NSUInteger level, NSUInteger sn, NSString * _Nonnull urlString) {
return [NSString stringWithFormat:@"%@---%@", @(level), @(sn)];
};
NSString *videoId = [Utils extractVideoIdFromUrl:originalUrl]; // extractVideoIdFromUrl is a function defined by yourself, you just need to extract video id from url
NSURL *parsedUrl = [[CBP2pEngine sharedInstance] parseStreamURL:originalUrl withVideoId:videoId];
- For SDK version < 1.10
// Set channelIdPrefix in p2pConfig before setting channelId! Connectivity with other platform should have the same channelIdPrefix.
CBP2pConfig *config = [CBP2pConfig defaultConfiguration];
config.channelIdPrefix = YOUR_UNIQUE_ID;
[[CBP2pEngine sharedInstance] startWithToken:YOUR_TOKEN andP2pConfig:config];
// If ts address in m3u8 is relative, you need to set the segmentid
[CBP2pEngine sharedInstance].segmentId = ^NSString * _Nonnull(NSUInteger level, NSUInteger sn, NSString * _Nonnull urlString) {
return [NSString stringWithFormat:@"%@---%@", @(level), @(sn)];
};
[CBP2pEngine sharedInstance].channelId = ^NSString * _Nonnull(NSString * _Nonnull urlString) {
NSString *videoId = [Utils extractVideoIdFromUrl:urlString]; // extractVideoIdFromUrl is a function defined by yourself, you just need to extract video id from url and return
return videoId;
};
Interconnect with other platform should ensure that both have the same channelIdPrefix and channelId.
# Dynamic ts path issue
Like dynamic m3u8 path issue, you should format a common segmentId for the same ts file. You can override the segment ID like this:
/*
level: The quality level
sn: The serial number of segment
segmentUrl: The url of segment
*/
[CBP2pEngine sharedInstance].segmentId = ^NSString * _Nonnull(NSUInteger level, NSUInteger sn, NSString * _Nonnull segmentUrl) {
return [Util format:segmentUrl];
};
# Setup HTTP headers
Some HTTP requests need to add header information such as referer or User-Agent for Anti-Leech or statistical requirements. It can be set via httpHeaders :
[CBP2pEngine sharedInstance].p2pConfig.httpHeaders = @{@"referer":@"XXX", @"User-Agent":@"XXX"};
# Switch Signal Address
Sometimes you need to change signal address in runtime to avoid overload of signal server:
CBP2pConfig *config = [CBP2pConfig defaultConfiguration];
config.wsSignalerAddr = @"wss://yoursignal2.com";
[CBP2pEngine sharedInstance].p2pConfig = config;
Please note that it will reset all fields of config in P2pEngine.
# Use Your Own STUN or TURN Server
STUN (Session Traversal Utilities for NAT) allows clients to discover their public IP address and the type of NAT they are behind. This information is used to establish the media connection. Although there are default STUN servers in this SDK, you can replace them with your own via P2PConfig. TURN (Traversal Using Relays around NAT) server is used to relay traffic if direct connection fails. You can config your TURN server in the same way as STUN.
#import <WebRTC/RTCIceServer.h>
NSMutableArray *ICEServers = [NSMutableArray array];
RTCIceServer *server = [[RTCIceServer alloc] initWithURLStrings:@[YOUR_STUN_OR_TURN_SERVER]];
[ICEServers addObject:server];
config.webRTCConfig = [[RTCConfiguration alloc] init];
config.webRTCConfig.iceServers = ICEServers;