更新记录
4.11.0(2024-11-12) 下载此版本
更新 SDK 4.18.0
4.10.0(2024-10-22) 下载此版本
SDK 4.17.0
4.9.0(2024-09-09) 下载此版本
BJY SDK 更新到 4.16.6
查看更多平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:5.0 - 12.0 | armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 | 适用版本区间:11 - 16 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
BJY-VideoPlayer_example
uniapp 点播回放plugin
1. 插件配置
为解决同时引入点播插件和直播插件编译报错,把两个插件的公共依赖 jar 和 aar 包放到 百家云点直播共用依赖插件,请务必同时依赖好此插件。
HBuilderX 导入本插件后,需要配置百家云个性域名
2. 在线点播
引用点播回放模块
// 引用点播回放模块
const playback = uni.requireNativePlugin("BJY-VideoPlayer-PlaybackUI")
2.1. 点播
普通点播
// 进入点播界面
startVideo() {
// VideoConfig 参数按需配置,如不需要设置,请传空对象‘{}’
playback.startVideo("160491264", "W7zE72DM4167ltDCxPWSwbXbP8gWUnGsUHbgqbvQ1rIKiF3VBQ50eg", {
// 用户唯一标识
"userId": "853145204",
// 用户昵称
"userName": "yongjiaming",
// 是否支持循环播放
"supportLooping": true,
// 是否支持记忆播放,即下次播放从上次关闭的时间点续播
"supportBreakPointPlay": true,
// 默认是否横屏播放
"isLandscape": true
})
}
带评论的点播,参考 https://dev.baijiayun.com/wiki/detail/65#-h4-12 ,在上边的 VideoConfig
中再传入
{
// 点播评论 token
"loginToken": "",
// 若为null,则显示本地默认头像
"avatar": ""
}
2.2. 标准视频组件
不同于 2.1 节整个跳转到原生播放器界面的方式,标准视频组件以 uniapp component 的形式映射为 js 组件,方便用户和其它组件混合排列展示(如视频播放器 + 课程列表的上下排列形式。
组件引用
<VideoPlayerViewComponent :style="{height: playerHeight + 'px', maxHeight: screenWidth + 'px'}" ref="playerView"
:videoConfig="videoConfig" @onerror="onError" @onplayingtimechange="TimeChange"
@onplayerstatus="onPlayerStatus" @ontogglescreen="Screen" @onexternalalbumclick="onExternalAlbumClick">
</VideoPlayerViewComponent>
状态监听
<script>
import {
setFullScreen
} from '@/utils/tool.js';
const {
statusBarHeight,
screenWidth,
screenHeight,
platform
} = uni.getSystemInfoSync();
export default {
data() {
return {
// 设置视频参数
videoConfig: {
// 视频 ID
"videoId": "160491264",
// token 为空则默认拿 videoId 去本地找下载记录尝试离线播放
"token": "W7zE72DM4167ltDCxPWSwbXbP8gWUnGsUHbgqbvQ1rIKiF3VBQ50eg",
// 用户唯一标识
"userId": "853145204",
// 用户昵称
"userName": "yongjiaming",
// 是否支持循环播放
"supportLooping": true,
// 是否支持记忆播放,即下次播放从上次关闭的时间点续播
"supportBreakPointPlay": true,
// 是否自动播放
"autoplay": false
},
isLandscape: false
}
},
computed: {
statusBarHeight() {
return this.isLandscape ? 0 : `${statusBarHeight}px`;
},
playerHeight() {
return this.isLandscape ? screenWidth : 211;
}
},
onLoad() {
console.log("onLoad");
},
methods: {
switchVideoSource() {
// 设置视频 vid,这个重复调可以切换视频源
this.$refs.playerView.setupOnlineVideo("189522041",
"bk5AAVT-dohjXPso7IvWEIXKsSLI9AhOBojKxgitZ5zDdvZpFsyklzG5JtrxIFp-");
},
play() {
// 播放
this.$refs.playerView.play();
},
pause() {
// 暂停播放
this.$refs.playerView.pause();
},
seek() {
// 快进、快退到目标时间戳,单位秒。
this.$refs.playerView.seekTo(10);
},
setPlayRate() {
// 设置播放倍速
this.$refs.playerView.setPlayRate(2.0);
},
destroy() {
// 销毁播放
this.$refs.playerView.destroy();
},
// 出错回调
onError: (map) => {
console.log("onError code=" + map.detail.code + ", message=" + map.detail.message);
},
// 播放进度回调
TimeChange: (map) => {
console.log("TimeChange currentTime=" + map.detail.currentTime + ", duration=" + map.detail
.duration);
},
// 播放器状态回调
/**
* 出错
STATE_ERROR,
未初始化
STATE_IDLE,
初始化
STATE_INITIALIZED,
数据已准备好,待播放
STATE_PREPARED,
播放中
STATE_STARTED,
暂停状态
STATE_PAUSED,
终止状态(已释放播放器实例)
STATE_STOPPED,
播放结束
STATE_PLAYBACK_COMPLETED
*/
onPlayerStatus(map) {
console.log("onPlayerStatus playerStatus=" + map.detail.playerStatus);
},
Screen(map) {
this.isLandscape = map.detail.isLandscape;
console.log("Screen isLandscape=" + this.isLandscape);
setFullScreen(this.isLandscape);
}
}
}
</script>
详见示例工程的 videoplayer-component.nvue
。
注意:iOS 切换横屏需要在 pages.json
配置 "pageOrientation": "auto"
,并且重新制作自定义基座才能生效。
2.3. 纯视频组件
纯视频组件,同 2.2 节标准视频组件的区别在于,纯视频组件仅映射原生视频播放组件,像进度条、手势操作、弹框、锁屏等均由 js 实现,保证了最大的灵活度。
对于追求最大自定义效果的客户,我们推荐使用 2.3 节的组件。
注意: 2.2 节 VideoPlayerViewComponent
标准视频组件功能齐全,与原生 SDK 同步迭代更新。
本节 BJYPlayerView
只提供一套开源的简易 UI 实现,客户可基于此二次开发,原则上不会继续迭代。对比 VideoPlayerViewComponent
缺失的跑马灯等功能,需要客户自行实现。
组件引用
<player
ref="player"
// 设置播放器参数
:playerConfig="playerConfig"
// 默认播放的视频 ID
:videoId="videoId"
// 默认播放的视频对应 token,为空则默认拿 videoId 去本地找下载记录尝试离线播放
:token="token"
:lists="lists"
@changeVideo="changeVideo">
</player>
data() {
return {
// 播放器配置项
playerConfig: {
// 用户唯一标识
"userId": "853145204",
// 用户昵称
"userName": "yongjiaming",
// 是否支持循环播放
"supportLooping": true,
// 是否支持记忆播放,即下次播放从上次关闭的时间点续播
"supportBreakPointPlay": true,
// 是否自动播放
"autoplay": true
},
// 视频列表
lists: [{
"videoId": "189522041",
"token": "Uqi1pxZOUbVjXPso7IvWEIXKsSLI9AhOASwauSQk-cDbeWcJ4TGqfzG5JtrxIFp-",
"videoTitle": "迪丽热巴绝美",
"videoTime": "0:04:25",
"videoCover": "https://www.baijiayun.com/video-cloud/asset/frontend/img/wechat_logo.png"
},
{
"videoId": "189352873",
"token": "sEsKxepQcfRjXPso7IvWEIDdozG7qgxnXL9qyN-79JTbeWcJ4TGqfzG5JtrxIFp-",
"videoTitle": "微微一笑很倾城",
"videoTime": "0:44:25",
"videoCover": "https://www.baijiayun.com/video-cloud/asset/frontend/img/wechat_logo.png"
},
{
"videoId": "184937822",
"token": "KidANdCBLwZjXPso7IvWENPCcwKvNplBZO5lNoz7ehjbeWcJ4TGqfzG5JtrxIFp-",
"videoTitle": "黑色幽默",
"videoTime": "0:04:42",
"videoCover": "https://www.baijiayun.com/video-cloud/asset/frontend/img/wechat_logo.png"
}
],
// 默认播放的视频 ID
videoId: '189522041',
// 默认播放的视频对应 token,为空则默认拿 videoId 去本地找下载记录尝试离线播放
token: 'Uqi1pxZOUbVjXPso7IvWEIXKsSLI9AhOASwauSQk-cDbeWcJ4TGqfzG5JtrxIFp-',
showVideoList: true
};
},
详细实现见插件示例工程 customizable-player.nvue
和 components
目录。
2.4. 画中画
iOS 端支持画中画功能需要在manifest.json 配置 "UIBackgroundModes": "audio",即配置后台运行能力:audio
3. 在线回放
// 进入普通回放
startPlayback() {
// 这里如果不传配置数据,也需要传一个空的map结构,不然iOS平台会崩溃
playback.startPlayback("22120569887615",
"FQj0pl0VChB5q0vfU4E4B08e8lOPKvV6OrdV7ckmSpUE_te8zzwG3_bRc2O3cISjCqdH1zJ1Si0", {})
}
// 进入长期课回放
startPlayback2() {
playback.startPlayback("22112282539916",
"Q0XEwmsRDdt5q0vfU4E4B0MFS1SOSH3P4kjMRfxhJjkE0tPQ2GN5wwT-17zPPAbfyY4TqPVTaj4Kp0fXMnVKLQ", {
"session_id": "202212080"
})
},
// 进入长期课裁剪版本回放
startPlayback3() {
playback.startPlayback("22092788575540",
"XFrvfzrsijh5q0vfU4E4B5G-Dj0S3FQS0TFaRSpvjWf9mEaeSMauHajPy2Z0h_U_5PSxzG5qDVQKp0fXMnVKLQ", {
"session_id": "202212220",
"clipedVersion": 1
})
}
4. 下载
// 引入下载模块
const downloadManager = uni.requireNativePlugin("BJY-VideoPlayer-Download")
// 初始化 DownloadManager
downloadManager.initModule()
// 获取下载记录,返回对象为 JsonArray,每个 JsonObject 对应一条下载记录
/**
{
// 视频分辨率,-1未知类型;0标清;1高清;2超清;3,720P;4,1080P;5 音频
"definition": 2,
// 房间号,仅回放有值,点播为空
"roomId": "22112282539916",
// 0 点播下载类型,1 回放下载类型
"type": 1,
// 下载文件大小,单位 byte
"downloadedLength": 4016792,
// 下载状态,0初始状态;1下载中;2暂停;3出错;4完成;5已取消
"status": 4,
// 回放长期课专有
"sessionId": ”202307050“,
// 视频 id
"videoId": ”190660972“,
// 总文件大小,单位 byte
"totalLength": 4016792,
// 视频时长,单位秒
"duration": 1233
}
*/
downloadManager.getAllDownloadInfo((jsonObj) => {
for (let i = 0; i < jsonObj.length; i++) {
const element = jsonObj[i];
console.log("第" + i + "个下载:" + JSON.stringify(element));
}
})
/**
* 下载点播视频
* videoId: 视频 id
* token: 视频 token
* userInfoString: 自定义字段,不需要则传空串“”
* callback: 回调,类型为 JsonObject
* JsonObject 字段如下
* {
event: 回调事件类型(String类型),分别为 、onError、onPaused、onStarted、onFinish、onDeleted
其它字段同下载记录中列举的
*
*/
downloadManager.downloadVideo("189522041",
"gSXewR2YNDpjXPso7IvWEIXKsSLI9AhOwO3UNMRVFsODsXW3VuiOyzG5JtrxIFp-",
"userInfoString", (jsonObj) => {
this.videoDownloadTips = jsonObj.event
if (jsonObj.event == "") {
this.videoDownloadTips += jsonObj.downloadedLength * 1.0 / jsonObj.totalLength
}
// 下载完成后自动播放
if (jsonObj.event == "onFinish") {
playback.startLocalVideo(jsonObj.videoId, jsonObj.videoPath, jsonObj.definition, {})
}
})
/**
* 下载回放
* roomId: 房间号
* sessionId: 长期课id,非长期课传 0
* userInfoString: 自定义字段,不需要则传空串“”
* token: token
* callback: 回调,类型为 JsonObject
* 字段同点播
*/
downloadManager.downloadPlayback("22112282539916", "202307050",
"CQNFkDoGFqljzZSuP5BQeK9UE5HaKY3CQbJRozbUo_aWipS34d0I5Z9eIcdJXH3qyMfGF222sWyMCTpCPak4Cg",
"userInfoString", (jsonObj) => {
this.playbackDownloadTips = jsonObj.event
if (jsonObj.event == "") {
this.playbackDownloadTips += jsonObj.downloadedLength * 1.0 / jsonObj.totalLength
}
// 下载完成后自动播放
if (jsonObj.event == "onFinish") {
playback.startLocalPlayback(jsonObj.roomId, jsonObj.sessionId, jsonObj.videoPath, jsonObj
.signalPath, jsonObj.definition, {})
}
})
// downloadVideo内部调了start,调了 downloadVideo 或者 downloadPlayback 之后才可以调 pause()、start()、cancelAndDeleteXXX()
// 开始下载
downloadManager.startVideo("videoId");
downloadManager.startPlayback("roomId", "sessionId");
// 暂停下载
downloadManager.pauseVideo("videoId");
downloadManager.pausePlayback("roomId", "sessionId");
// 点播取消并删除下载文件
downloadManager.cancelAndDeleteVideo("videoId");
// 回放取消并删除下载文件
downloadManager.cancelAndDeletePlayback("roomId", "sessionId");
5. 离线点播回放
vue 调用
请确保videoId/RoomId 有对应的下载记录,否则无法正常调起播放页面
// 播本地点播
playback.startLocalVideo(jsonObj.videoId, {})
// 播本地回放
playback.startLocalPlayback(jsonObj.roomId, jsonObj.sessionId, {})
插件代码
/**
* 播放离线点播
*
* @param videoId 视频 id
* @param videoConfig 视频配置项
*/
@UniJSMethod(uiThread = true)
public void startLocalVideo(String videoId, JSONObject videoConfig)
/**
* 播放离线回放
* @param roomId 房间号
* @param sessionId 长期课 sessionId
* @param videoConfig 视频配置
*/
@UniJSMethod(uiThread = true)
public void startLocalPlayback(String roomId, String sessionId, String videoPath, String signalPath, int definition, JSONObject videoConfig)