P2P流媒体引擎

vuePress-theme-reco    2018 - 2021
P2P流媒体引擎 P2P流媒体引擎

Choose mode

  • dark
  • auto
  • light
在线文档
  • 快速入门
  • Web SDK

    • Hls.js
    • MP4
    • Dash.js
    • Shaka-Player
    • 大文件下载
    • 网站加速
  • Android SDK
  • iOS SDK
  • Flutter SDK
价格
解决方案
  • 机顶盒/IPTV
控制台
关于我们
GitHub
language
  • English
  • 简体中文

在线文档
  • 快速入门
  • Web SDK

    • Hls.js
    • MP4
    • Dash.js
    • Shaka-Player
    • 大文件下载
    • 网站加速
  • Android SDK
  • iOS SDK
  • Flutter SDK
价格
解决方案
  • 机顶盒/IPTV
控制台
关于我们
GitHub
language
  • English
  • 简体中文
  • 快速入门
  • 常见问题
  • 信令服务
  • P2P优化
  • 控制台

    • 绑定域名/AppId
    • 数据分析
    • P2P控制
    • Restful API
  • Hls.js SDK

    • 简介
    • 使用方法
    • 第三方播放器
    • CMS集成
    • API文档
    • CDN
    • 更新日志
  • 安卓 SDK

    • 简介
    • 使用方法
    • API文档
    • 更新日志
  • iOS SDK

    • 简介
    • 使用方法
    • API文档
    • 更新日志
  • Flutter SDK

    • 简介
    • 使用方法
    • API文档
    • 更新日志
  • 网站加速 SDK

    • 简介
    • 使用方法
    • API文档
    • 更新日志
  • Shaka-Player SDK

    • 简介
    • 使用方法
    • 第三方播放器
    • API文档
    • 更新日志
  • Web MP4 SDK

    • 简介
    • 使用方法
    • 第三方播放器
    • API文档
    • 更新日志
  • Dash.js SDK

    • 简介
    • 使用方法
    • 第三方播放器
    • API文档
    • 更新日志
  • 大文件下载 SDK

    • 简介
    • 使用方法
    • API文档
    • 更新日志
  • 安卓 SDK 1.x

    • 简介
    • 使用方法
    • API文档
      • P2P配置
      • P2pEngine
      • 高级用法
    • 更新日志
  • 更多

    • 技术原理
    • 用户服务协议

API文档

vuePress-theme-reco    2018 - 2021

API文档


# P2P配置

用建造者模式实例化 P2pConfig,以下的参数是默认值:

P2pConfig config = new P2pConfig.Builder()
    .logEnabled(false)                                // 是否打印日志
    .logLevel(LogLevel.WARN)                          // 打印日志的级别
    .announce("https://tracker.cdnbye.com/v1")        // tracker服务器地址
    .wsSignalerAddr("wss://signal.cdnbye.com")        // 信令服务器地址
    .downloadTimeout(15_000, TimeUnit.MILLISECONDS)   // HTTP下载ts文件超时时间
    .dcDownloadTimeout(6_000, TimeUnit.MILLISECONDS)  // datachannel下载二进制数据的最大超时时间
    .localPort(0)                                     // 本地代理服务器的端口号(默认随机端口)
    .diskCacheLimit(1024*1024*1024)                   // 点播模式下P2P在磁盘缓存的最大数据量(设为0可以禁用磁盘缓存)
    .memoryCacheCountLimit(30)                        // P2P在内存缓存的最大数据量,用ts文件个数表示
    .p2pEnabled(true)                                 // 开启或关闭p2p engine
    .wifiOnly(false)                                  // 是否只在wifi和有线网络模式上传数据(建议在云端设置)
    .withTag("unknown")                               // 用户自定义的标签,可以在控制台查看分布图
    .webRTCConfig(null)                               // 通过webRTCConfig来修改WebRTC默认配置
    .maxPeerConnections(15)                           // 最大连接节点数量
    .useHttpRange(true)                               // 在可能的情况下使用Http Range请求来补足p2p下载超时的剩余部分数据
    .httpHeaders(null)                                // 设置请求ts和m3u8时的HTTP请求头
    .channelIdPrefix(null)                            // 如果使用自定义的channelId,则此字段必须设置,且长度必须在5到15个字符之间,建议设置成你所在组织的唯一标识
    .isSetTopBox(false)                               // 如果运行于机顶盒请设置成true
    .fastStartup(true)                                // 前几个ts直接向服务器请求,不走代理服务器,提高起播速度
    .playlistMaxRetries(2)                            // 本地代理请求m3u8或者mpd失败时的最大重试次数
    .build();  
P2pEngine.initEngine(getApplicationContext(), token, config);

# P2pEngine

实例化P2pEngine,获得一个全局单例:

P2pEngine engine = P2pEngine.initEngine(Context context, String token, P2pConfig config);

参数说明:

参数 类型 是否必须 说明
context Context 是 建议使用Application 的 Context 对象。
token String 是 CDNBye分配的token。
config P2pConfig 否 自定义配置。

# 切换源

当播放器切换到新的播放地址时,只需要将新的播放地址(m3u8)传给 P2pEngine,从而获取新的本地播放地址:

String newParsedURL = P2pEngine.getInstance().parseStreamUrl(url);

# P2pEngine API

# P2pEngine.Version

当前插件的版本号。

# P2pEngine.protocolVersion

获取 P2P 协议的版本号,与其他平台互通的前提是 P2P 协议版本号相同。

# P2pEngine.getInstance()

获取 P2pEngine 的单例。

# engine.parseStreamUrl(String url)

将原始播放地址(m3u8)转换成本地代理服务器的地址。

# engine.parseStreamUrl(String url, String videoId)

将原始播放地址(m3u8)转换成本地代理服务器的地址,同时传入videoId用以构造channelId。

# engine.isConnected()

是否已与CDNBye后台建立连接。

# engine.stopP2p()

停止P2P加速并释放资源,一般不需要调用。SDK采用"懒释放"的策略,只有在重启p2p的时候才释放资源。对于性能较差的设备起播耗时可能比较明显,建议在视频播放之前提前调用 engine.stopP2p() 。

# engine.restartP2p()

重启P2P加速服务,一般不需要调用。

# engine.getPeerId()

获取对等连接的id。

# engine.setHttpHeaders(Map<String, String> headers)

动态设置请求ts和m3u8时的HTTP请求头。

# engine.shutdown()

停止P2P并关闭代理服务器。

# P2P统计

通过 P2pStatisticsListener 来监听P2P下载信息:

engine.addP2pStatisticsListener(new P2pStatisticsListener() {
    @Override
    public void onHttpDownloaded(long value) {
    }

    @Override
    public void onP2pDownloaded(long value) {
    }

    @Override
    public void onP2pUploaded(long value) {
    }

    @Override
    public void onPeers(List<String> peers) {
    }
    
    @Override
    public void onServerConnected(boolean connected) {
    }
});

下载和上传数据量的单位是KB。

# 高级用法

# 直播流P2P优化

在直播模式下,为了增强P2P效果,建议通过 setPlayStats ,将从当前播放时间到缓冲前沿的时间间隔回调给p2p engine。

import com.cdnbye.sdk.PlayerStatsCallback;

P2pEngine.getInstance().setPlayStats(new PlayerStatsCallback() {
    @Override
    public long onBufferedDuration() {
        // Exoplayer 单位:毫秒
        return player.getBufferedPosition() - player.getCurrentPosition();
    }
});

# 解决动态m3u8路径问题

某些流媒体提供商的m3u8是动态生成的,不同节点的m3u8地址不一样,例如example.com/clientId1/streamId.m3u8和example.com/clientId2/streamId.m3u8, 而本插件默认使用m3u8地址(去掉查询参数)作为channelId。这时候就要构造一个共同的chanelId,使实际观看同一直播/视频的节点处在相同频道中。构造channelId方法如下:

  • SDK 版本 >= 1.10
// 必须先在 p2pConfig 设置 channelIdPrefix ,才能自定义 channelId ! 与其他平台互通需要构造相同的 channelIdPrefix 。
P2pConfig config = new P2pConfig.Builder() 
    .channelIdPrefix(YOUR_UNIQUE_ID)                           
    .build();  
P2pEngine.initEngine(getApplicationContext(), token, config);
// 如果m3u8里的ts是相对地址需要设置segmentId
P2pEngine.getInstance().setSegmentId(new SegmentIdCallback() {   
    @Override
    public String onSegmentId(int level, long sn, String segmentUrl) {
        return String.format("%d-%d", level, sn);
    }
});
String videoId = extractVideoIdFromUrl(urlString);     // extractVideoIdFromUrl 需要自己定义,可以抽取url中的视频ID作为结果返回
String parsedUrl = P2pEngine.getInstance().parseStreamUrl(urlString, videoId);
  • SDK 版本 < 1.10
import com.cdnbye.sdk.ChannelIdCallback;

// 必须先在 p2pConfig 设置 channelIdPrefix ,才能自定义 channelId ! 与其他平台互通需要构造相同的 channelIdPrefix 。
P2pConfig config = new P2pConfig.Builder() 
    .channelIdPrefix(YOUR_UNIQUE_ID)                           
    .build();  
P2pEngine.initEngine(getApplicationContext(), token, config);
// 如果m3u8里的ts是相对地址需要设置segmentId
P2pEngine.getInstance().setSegmentId(new SegmentIdCallback() {
    @Override
    public String onSegmentId(int level, long sn, String segmentUrl) {
        return String.format("%d-%d", level, sn);
    }
});
P2pEngine.getInstance().setChannelId(new ChannelIdCallback() {
    @Override
    public String onChannelId(String urlString) {
        return extractVideoIdFromUrl(urlString);    // extractVideoIdFromUrl 需要自己定义,可以抽取url中的视频ID作为结果返回
  
    }
});

如果要与其他平台互通,则必须确保两者拥有相同的 channelIdPrefix 和 channelId 。

# 解决动态ts路径问题

类似动态m3u8路径问题,相同ts文件的路径也可能有差异,这时候需要忽略ts路径差异的部分。插件默认用ts的绝地路径(url)来标识每个ts文件,所以需要通过钩子函数重新构造标识符。可以按如下设置:

/*
    level: The quality level
    sn: The serial number of segment
    segmentUrl: The url of segment
*/
engine.setSegmentId(new SegmentIdCallback() {
    @Override
    public String onSegmentId(int level, long sn, String segmentUrl) {
        return format(segmentUrl);
    }
});

# 设置HTTP请求头

出于防盗链或者统计的需求,有些HTTP请求需要加上 referer 或者 User-Agent 等头信息,可以通过 setHttpHeaders 进行设置:

Map headers = new HashMap();
headers.put("referer", "XXX");
headers.put("User-Agent", "XXX");
engine.setHttpHeaders(headers);

# 切换信令

某些场景下需要动态修改信令地址,防止单个信令负载过大,例如根据播放地址的哈希值选择信令。可以通过调用 engine.setConfig(config) 运行时动态调整配置,示例如下:

P2pConfig config = new P2pConfig.Builder()
        .wsSignalerAddr("wss://yoursignal2.com")
        .build();
P2pEngine.getInstance().setConfig(config);

需要注意的是这个方法会重置 P2pEngine 的所有config,因此之前已经修改的字段需要再设置一次以保持一致。

# 自行配置 STUN 和 TURN 服务器地址

STUN用于p2p连接过程中获取公网IP地址,TURN则可以在p2p连接不通时用于中转数据。本SDK已内置公开的STUN服务,开发者可以通过P2pConfig来更换STUN地址。TURN服务器则需要开发者自行搭建,可以参考coturn 。

import org.webrtc.PeerConnection;
import org.webrtc.PeerConnection.RTCConfiguration;

List<PeerConnection.IceServer> iceServers = new ArrayList<>();
iceServers.add(PeerConnection.IceServer.builder(YOUR_STUN_OR_TURN_SERVER).createIceServer());
RTCConfiguration rtcConfig = new RTCConfiguration(iceServers);
P2pConfig config = new P2pConfig.Builder()
    .webRTCConfig(rtcConfig)
    .build();