SwarmCloud

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

Choose mode

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

    • HLS(m3u8)
    • Shaka-Player
    • Dash.js
    • MP4
    • 大文件下載
  • 安卓/安卓TV SDK

    • v3 (安卓5.0+)
    • v2 (安卓4.4+)
  • iOS/tvOS/macOS SDK
定價
關於我們
生態
實時地球
管理面板
GitHub (opens new window)
language
  • English
  • 中文

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

    • HLS(m3u8)
    • Shaka-Player
    • Dash.js
    • MP4
    • 大文件下載
  • 安卓/安卓TV SDK

    • v3 (安卓5.0+)
    • v2 (安卓4.4+)
  • iOS/tvOS/macOS SDK
定價
關於我們
生態
實時地球
管理面板
GitHub (opens new window)
language
  • English
  • 中文
  • 快速入門
  • 常見問題
  • Tracker服務
  • 信令服務
  • P2P優化
  • 管理面板

  • Web HLS SDK

  • 安卓 SDK v3

  • 安卓 SDK v2

    • 簡介
    • 使用方法
    • API文档
      • P2P配置
      • P2pEngine
      • 高级用法
    • 更新日誌
  • iOS/tvOS/macOS SDK

  • Flutter SDK

  • Shaka-Player SDK

  • Dash.js SDK

  • Hls.js SDK

  • Web MP4 SDK

  • 大文件下載 SDK

  • 更多

API文档

vuePress-theme-reco SwarmCloud    2018 - 2023

API文档


SwarmCloud

# P2P配置

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

P2pConfig config = new P2pConfig.Builder()
    .logEnabled(false)                                // 是否打印日志
    .logLevel(LogLevel.WARN)                          // 打印日志的级别
    .announce("https://tracker.cdnbye.com/v1")        // tracker服务器地址
    .AnnounceLocation(AnnounceLocation.China)         // tracker服务器地址所在国家的枚举,分为China、HongKong、USA
    .downloadTimeout(30_000, TimeUnit.MILLISECONDS)   // HTTP下载ts文件超时时间
    .localPortHls(0)                                  // HLS本地代理服务器的端口号(默认随机端口,设置-1关闭Hls代理)
    .localPortMp4(0)                                  // MP4本地代理服务器的端口号(默认随机端口,设置-1关闭Mp4代理)
    .localPortDash(0)                                 // DASH本地代理服务器的端口号(默认随机端口,设置-1关闭Dash代理)
    .diskCacheLimit(1500*1024*1024)                   // 点播模式下P2P在磁盘缓存的最大数据量(设为0可以禁用磁盘缓存)
    .memoryCacheCountLimit(30)                        // P2P在内存缓存的最大数据量,用ts文件个数表示
    .p2pEnabled(true)                                 // 开启或关闭p2p engine
    .withTag(null)                                    // 用户自定义的标签,可以在控制台查看分布图
    .webRTCConfig(null)                               // 通过webRTCConfig来修改WebRTC默认配置
    .maxPeerConnections(20)                           // 最大连接节点数量
    .useHttpRange(true)                               // 在可能的情况下使用Http Range请求来补足p2p下载超时的剩余部分数据
    .httpHeadersForHls(null)                          // 设置请求ts和m3u8时的HTTP请求头
    .httpHeadersForMp4(null)                          // 设置请求mp4时的HTTP请求头
    .httpHeadersForDash(null)                         // 设置请求dash描述文件和媒体文件时的HTTP请求头
    .httpHeadersForFile(null)                         // 设置文件下载请求时的HTTP请求头
    .isSetTopBox(false)                               // 如果运行于机顶盒请设置成true
    .fileCacheDirectory(null)                         // 文件下载的文件保存路径,如果挂载了SD卡默认是"/Android/data/[app_package_name]/cache/p2p-engine",
    .pieceLengthForMp4(1024*1024)                     // MP4的切片大小,HTTP下载和P2P传输的基本单位
    .pieceLengthForFile(1024*1024)                    // 文件下载的切片大小,HTTP下载和P2P传输的基本单位
    .waitForPeer(false)                               // 优先尝试从对等端下载前几片数据,可以提高P2P比例,但可能会增加起播延时          
    .waitForPeerTimeout(4500)                         // waitForPeer的超时时间,超时后恢复从http下载
    .httpLoadTime(2_000)                              // P2P下载超时后留给HTTP下载的时间
    .sharePlaylist(false)                             // 是否允许m3u8文件的P2P传输 
    .logPersistent(false)                             // 是否将日志持久化到外部存储(Environment.getExternalStorageDirectory()路径下的logger文件夹)
    .geoIpPreflight(true)                             // 直播模式下向在线IP数据库请求ASN等信息,从而获得更准确的调度   
    .build();  
P2pEngine.init(getApplicationContext(), token, config);

# P2pEngine

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

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

参数说明:

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

# 切换源

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

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

# P2pEngine API

# P2pEngine.Version

当前插件的版本号。

# P2pEngine.protocolVersion

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

# P2pEngine.getInstance()

获取 P2pEngine 的单例。

# engine.parseStreamUrl(String url)

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

# engine.parseStreamUrl(String url, String videoId)

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

# engine.isConnected()

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

# engine.stopP2p()

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

# engine.restartP2p()

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

# engine.getPeerId()

获取对等连接的id。

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

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

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

动态设置请求mp4文件时的HTTP请求头。

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

动态设置文件下载时的HTTP请求头。

# engine.disableP2p()

运行时动态关闭P2P,在播放下一个媒体文件时才生效。

# engine.enableP2p()

运行时动态开启P2P,在播放下一个媒体文件时才生效。

# engine.shutdown()

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

# engine.downloadFile(String url)

开始下载url对应的文件。
返回 DownloadInfo 对象,包含了下载信息,包括:
long getFileSize() 获取文件总大小
String getUrl() 获取文件url
String getFileName() 获取文件名
String getMimeType() 获取http响应头的 MimeType
File getCacheFile() 获取文件保存路径
boolean isCached() 文件是否已经缓存了,如果是的话直接可以使用,不需要下载
boolean isInProgress() 文件是否正在下载

# engine.downloadFile(String url, String fileName)

开始下载url对应的文件,其中 fileName 是保存在本地的文件名。

# engine.downloadFile(String url, String fileName, File cacheDir)

开始下载url对应的文件,其中 fileName 是保存在本地的文件名, cacheDir 是文件保存路径。

# engine.downloadFile(String url, String fileName,String channelId)

开始下载url对应的文件,其中 fileName 是保存在本地的文件名,channelId 用于标识p2p频道。

# engine.downloadFileNormally(String url)

普通文件下载,不使用P2P。

# engine.stopFileDownload()

停止文件下载,关闭P2P并释放占用的記憶體。

# engine.pauseFileDownload()

暂停文件下载,此时P2P文件交换正常进行。

# engine.deleteDownloadedFile(File file)

删除正在下载或已下载的文件file。

# P2P统计

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

engine.addP2pStatisticsListener(new P2pStatisticsListener() {
            @Override
            public void onHttpDownloaded(long value) {
            }
            @Override
            public void onP2pDownloaded(long value, int speed) {
            }
            @Override
            public void onP2pUploaded(long value, int speed) {
            }
            @Override
            public void onPeers(List<String> peers) {
            }
            @Override
            public void onServerConnected(boolean connected) {
            }
        });

下载和上传数据量的单位是KB,下载速度的单位是KB/s。

# 监听文件下载情况

engine.registerFileDownloadListener(new FileDownloadListener() {
   @Override
   public void onDownloadFailed(Throwable e) {
       // fallback
   }
   @Override
   public void onDownloadFinished(File cacheFile, String url) {
       // get downloaded file here
   }
   @Override
   public void onCacheAvailable(File cacheFile, String url, int percentsAvailable) {
       // show progress to user
   }
});

# 移除文件下载监听

engine.unregisterFileDownloadListener(FileDownloadListener listener)

# 高级用法

# 回调播放器信息

在直播或者MP4播放模式下,为了增强P2P效果并提高播放流畅度,建议通过 setPlayerInteractor ,将从当前播放时间到缓冲前沿的时间间隔回调给p2p engine。

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

在点播模式下,一个视频的时长可能比较大,如果能在节点匹配的时候优先匹配播放时间接近的节点则有助于P2P效果的提升,要实现这个功能需要在SDK层面获取播放器的当前播放时间:

import com.cdnbye.core.p2p.PlayerInteractor;
P2pEngine.getInstance().setPlayerInteractor(new PlayerInteractor() {
    public long onCurrentPosition() {
        // Exoplayer 单位:毫秒
        return player.getCurrentPosition();
    }
});

# 解决动态url路径问题

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

  • HLS & DASH & MP4
String videoId = extractVideoIdFromUrl(urlString);     // extractVideoIdFromUrl 需要自己定义,可以抽取url中的视频ID作为结果返回
String parsedUrl = P2pEngine.getInstance().parseStreamUrl(urlString, videoId);
  • 文件下载
String fileId = extractFileIdFromUrl(urlString);     // extractFileIdFromUrl 需要自己定义,可以抽取url中的文件ID作为结果返回
P2pEngine.getInstance().downloadFile(url, url, fileId);

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

# 解决动态ts路径问题

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

/*
    streamId: The id of stream
    sn: The serial number of segment
    segmentUrl: The url of segment
    range: Byte range of segment
*/
// For HLS
P2pEngine.getInstance().setHlsSegmentIdGenerator(new HlsSegmentIdGenerator() {
    @Override
    public String onSegmentId(String streamId, long sn, String segmentUrl, String range) {
        return extractIdFromSegment(segmentUrl, range);
    }
});
// For DASH
P2pEngine.getInstance().setDashSegmentIdGenerator(new DashSegmentIdGenerator() {
    @Override
    public String onSegmentId(String streamId, String segmentUrl, String range) {
        return extractIdFromSegment(segmentUrl, range);
    }
});

# 设置HTTP请求头

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

Map headers = new HashMap();
headers.put("User-Agent", "XXX");
engine.setHttpHeadersForHls(headers);      // For hls playback
// engine.setHttpHeadersForDash(headers);      // For dash playback
// engine.setHttpHeadersForMp4(headers);     // For mp4 playback
// engine.setHttpHeadersForFile(headers);    // For file download

# 传入自定义 OkHttpClient

OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new YourInterceptor())
                .build();
P2pConfig config = new P2pConfig.Builder()
        .okHttpClient(httpClient)
        .build();

# 扩展支持的HLS媒体文件

默认只支持".ts"等为后缀的常见文件类型,如果需要支持类似".image"的文件类型,需要做以下配置:

P2pConfig config = new P2pConfig.Builder()
    .hlsMediaFiles(new ArrayList<String>(){{
        add("mp4");
        add("ts");
        add("m4s");
        add("m4v");
        add("image");
    }})
    .build();

一般HLS媒体文件以".xx"结尾,但也有例外情况,比如其他任意字符结尾,为了让本地代理能识别出这些扩展,需要做以下配置:

// 假如媒体文件url是 http://example.com/pathxxx
P2pConfig config = new P2pConfig.Builder()
    .hlsMediaFileExtensions(new ArrayList<String>(){{
        add("xxx");
    }})
    .build();

# P2P优先策略

由于建立P2P连接需要时间,默认情况下前几片用HTTP下载。可以通过配置参数,等待P2P建立连接后优先用P2P下载,从而提升P2P效果,但可能会带来延时,建议在热度比较大的频道开启。

P2pConfig config = new P2pConfig.Builder()
    .waitForPeer(true)
    .waitForPeerTimeout(4500)      // 可以根据具体场景设置超时时间
    .build();

暂不支持MPEG-DASH和多码率HLS。

# 拦截m3u8文件

由于 SDK 需要解析m3u8的内容,如果您用了加密的m3u8,则需要使用拦截器拦截并返回标准的m3u8文件:

P2pEngine.getInstance().setHlsInterceptor(new HlsInterceptor() {
    @Override
    public byte[] interceptPlaylist(byte[] text, String url) {
        return handlePlaylist(text, url);
    }
});

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

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

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();

# 监听SDK异常信息

由于网络、服务器和算法bug等原因,SDK可能会出现异常,可以通过 registerExceptionListener 方法来监听异常:

P2pEngine.getInstance().registerExceptionListener(new EngineExceptionListener() {
    @Override
    public void onTrackerException(EngineException e) {
        // Tracker Exception
    }
    @Override
    public void onSignalException(EngineException e) {
        // Signal Server Exception
    }
    @Override
    public void onSchedulerException(EngineException e) {
        // Scheduler Exception
    }
    @Override
    public void onOtherException(EngineException e) {
        // Other Exception
    }
});