# 游戏对局回放(选接)
游戏对局回放是一组录制游戏画面来生成对局回放,并可以将对局回放分享给好友的API,收到分享链接的B站用户可点击链接查看回放,或进入游戏等。
注意事项
该能力暂不支持使用B站开发者工具调试,请使用真机预览测试!
# 录制游戏画面
# 接口说明
用于录制游戏画面来生成对局回放。
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 先判断 gameRecorder 是否存在再使用
// 因为当用户的客户端基础库版本过低时,调用 sdkInstance.getGameRecorder 接口将返回 undefined
if (gameRecorder) {
// 用于检查是否支持录制游戏画面,返回一个 Boolean 值
gameRecorder.isFrameSupported();
// 用于检查是否支持录制游戏画面时,同步录制游戏音频信息,返回一个 Boolean 值
gameRecorder.isSoundSupported();
// 用于检查是否支持调节录制视频的音量,返回一个 Boolean 值
gameRecorder.isVolumeSupported();
// 用于检查是否支持调节录制视频的播放速率,返回一个 Boolean 值
gameRecorder.isAtempoSupported();
// 监听录制事件,当对应事件触发时,回调函数会被执行,详见下文说明
gameRecorder.on(event, callback);
// 取消监听录制事件,当对应事件触发时,回调函数不再执行,详见下文说明
gameRecorder.off(event, callback);
// 开始录制游戏画面,参数 options 可选,返回一个 Promise 对象
gameRecorder.start(options?);
// 暂停录制游戏画面,返回一个 Promise 对象
gameRecorder.pause();
// 恢复录制游戏画面,返回一个 Promise 对象
gameRecorder.resume();
// 结束录制游戏画面,结束录制后可以发起分享,返回一个 Promise 对象
gameRecorder.stop();
// 取消录制游戏画面,此时已经录制的内容将被丢弃,返回一个 Promise 对象
gameRecorder.abort();
}
// 不存在或不支持录制时,弹出相应提示
else {
sdkInstance.modal.message("暂不支持此功能");
}
最低基础库版本要求
当用户的客户端基础库版本过低时,调用 sdkInstance.getGameRecorder() 接口将返回 undefined,并在正式版环境下于控制台输出错误提示(非正式版环境下,以弹窗形式展示),需要游戏客户端对返回值做兼容处理!
# 录制器
调用 sdkInstance.getGameRecorder() (opens new window) 接口将返回一个全局单例录制器 GameRecorder (opens new window)。录制游戏画面是一项比较消耗性能的能力,在某些系统、设备上无法进行游戏画面录制,因此在调用游戏画面录制能力前,需先判断当前环境是否支持该能力,如下所示:
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 判断是否支持录制游戏画面
if (gameRecorder && gameRecorder.isFrameSupported()) {
// 若支持,再执行后续相关操作
// ......
}
// 不存在或不支持录制时,弹出相应提示
else {
sdkInstance.modal.message("暂不支持此功能");
}
所有和录制有关的API都挂载在 GameRecorder (opens new window) 对象上:
- GameRecorder.isFrameSupported() (opens new window) 是否支持录制游戏画面
- GameRecorder.isSoundSupported() (opens new window) 是否在录制游戏画面的同时支持录制游戏音频的信息
- GameRecorder.isVolumeSupported() (opens new window) 是否支持调节录制视频的音量
- GameRecorder.isAtempoSupported() (opens new window) 是否支持调节录制视频的播放速率
- GameRecorder.on(event, callback) (opens new window) 监听录制事件
- GameRecorder.off(event, callback) (opens new window) 取消监听录制事件
- GameRecorder.start(options?) (opens new window) 开始录制游戏画面
- GameRecorder.pause() (opens new window) 暂停录制游戏画面
- GameRecorder.resume() (opens new window) 恢复录制游戏画面
- GameRecorder.stop() (opens new window) 结束录制游戏画面
- GameRecorder.abort() (opens new window) 放弃录制游戏画面
调用 GameRecorder.start(options?) (opens new window) 开始录制,调用 GameRecorder.stop() (opens new window) 结束录制:
// 监听录制开始事件,回调函数被执行时表示录制已开始
gameRecorder.on("start", function() {
// 真正开始录制 5 秒后结束录制
setTimeout(function() {
gameRecorder.stop();
}, 5000);
});
// 监听录制结束事件,回调函数被执行时表示录制已完成
gameRecorder.on("stop", function(result) {
console.log(`对局回放时长: ${result.duration}`);
});
// 开始录制
gameRecorder.start();
如果在录制过程中有玩家思考等待等过程,可以调用 GameRecorder.pause() (opens new window) 暂停录制,然后再用 GameRecorder.resume() (opens new window) 恢复录制:
// 监听录制暂停事件,回调函数被执行时表示录制已暂停
gameRecorder.on("pause", function() {
// 真正开始暂停 5 秒后恢复录制
setTimeout(function() {
gameRecorder.resume();
}, 5000);
});
// 监听录制恢复事件,回调函数被执行时表示录制已恢复
gameRecorder.on("resume", function() {
console.log("录制已恢复");
});
// 暂停录制
gameRecorder.pause();
如果想舍弃已经在录制的视频,可以调用 GameRecorder.abort() (opens new window):
// 监听录制取消事件,回调函数被执行时表示录制已取消,已经录制的内容将被丢弃
gameRecorder.on("abort", function() {
console.log("录制已取消");
});
// 取消录制
gameRecorder.abort();
注意事项
如果 stop 事件被触发,则表示已经有一个录制好的视频被输出来了;录制好的视频保存在B站客户端内部,不能被访问到,也不能直接播放,只能通过分享按钮发送给好友;客户端内部只会保存最近一次录制的视频,发起分享时也只会分享这个最近一次录制的视频!
# 监听录制事件
GameRecorder.on(event, callback) (opens new window) 用于监听录制事件,包含 event 和 callback 两个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
| 选项 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| event | string | 是 | -- | 事件类型
|
| callback | function | 是 | -- | 事件触发时执行的回调函数 |
注意事项
当事件类型为 stop、timeUpdate、error 时,其对应的事件回调函数参数各不相同,其它事件回调函数都是无参的。
当 stop 事件触发时,其回调函数的参数说明如下表所示:
| 选项 | 类型 | 说明 |
|---|---|---|
| duration | number | 视频时长,单位毫秒 |
// 监听录制结束事件
gameRecorder.on("stop", function(result) {
console.log(result.duration); // 视频时长
});
当 timeUpdate 事件触发时,其回调函数的参数说明如下表所示:
| 选项 | 类型 | 说明 |
|---|---|---|
| currentTime | number | 当前视频录制到第几秒 |
// 监听录制时间更新事件
gameRecorder.on("timeUpdate", function(result) {
console.log(result.currentTime); // 当前视频录制到第几秒
});
当 error 事件触发时,其回调函数的参数说明如下表所示:
| 选项 | 类型 | 说明 |
|---|---|---|
| error | object | 错误对象 |
| error.code | number | 错误码 |
| error.message | string | 错误信息 |
// 监听录制错误事件
gameRecorder.on("error", function(result) {
console.log(result.error.code); // 错误码
console.log(result.error.message); // 错误信息
});
# 取消监听录制事件
GameRecorder.off(event, callback) (opens new window) 用于取消监听录制事件,包含 event 和 callback 两个参数,当对应事件触发时,回调函数不再执行;参数说明如下表所示:
| 选项 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| event | string | 是 | -- | 事件类型
|
| callback | function | 是 | -- | 事件触发时不再执行的回调函数 |
# 开始录制
GameRecorder.start(options?) (opens new window) 用于开始录制游戏画面;参数说明如下表所示:
| 选项 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| fps | number | 否 | 24 | 视频帧率(fps) |
| bitrate | number | 否 | 1000 | 视频比特率(kbps),最小值 600,最大值 3000 |
| gop | number | 否 | 12 | 视频关键帧间隔 |
| duration | number | 否 | 7200 | 视频时长限制,单位为秒;最小值 5,最大值 7200,到达指定时长后不会再录制,但仍然需要手动调用 GameRecorder.stop() 来结束录制 |
| hookBgm | boolean | 否 | true | 是否录制游戏音效 |
# 暂停录制
GameRecorder.pause() (opens new window) 用于暂停录制游戏画面。
# 恢复录制
GameRecorder.resume() (opens new window) 用于恢复录制游戏画面。
# 结束录制
GameRecorder.stop() (opens new window) 用于结束录制游戏画面,结束录制后可以发起分享。
# 放弃录制
GameRecorder.abort() (opens new window) 用于放弃录制游戏画面,此时已经录制的内容将被丢弃。
# 示例代码
注:示例代码中的参数或选项均为演示数据,仅供参考,谢谢!
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 判断 gameRecorder 是否存在再使用,若存在且支持录制,则优先注册好相关的事件监听
// 因为当用户的客户端基础库版本过低时,调用 sdkInstance.getGameRecorder 接口将返回 undefined
if (gameRecorder && gameRecorder.isFrameSupported()) {
// 监听录制开始事件
gameRecorder.on("start", function() {
sdkInstance.modal.message("录制已开始");
});
// 监听录制暂停事件
gameRecorder.on("pause", function() {
sdkInstance.modal.message("录制已暂停");
});
// 监听录制恢复事件
gameRecorder.on("resume", function() {
sdkInstance.modal.message("录制已恢复");
});
// 监听录制结束事件
gameRecorder.on("stop", function(result) {
sdkInstance.modal.message("录制已结束");
});
// 监听录制取消事件
gameRecorder.on("abort", function() {
sdkInstance.modal.message("录制已取消");
});
// 监听录制时间更新事件
gameRecorder.on("timeUpdate", function(result) {
sdkInstance.modal.message("录制进行中");
});
// 监听录制错误事件
gameRecorder.on("error", function(result) {
sdkInstance.modal.message(result.error && result.error.message ? result.error.message : "录制出错");
});
}
// 绘制"开始录制"按钮,并在点击时调用 gameRecorder.start() 开始录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "开始录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder || !gameRecorder.isFrameSupported()) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 开始录制
gameRecorder.start().then(function(result) {
console.log(result);
}).catch(function(error) {
console.log(error);
});
}
});
// 绘制"结束录制"按钮,并在点击时调用 gameRecorder.stop() 结束录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "结束录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder || !gameRecorder.isFrameSupported()) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 结束录制
gameRecorder.stop().then(function(result) {
console.log(result);
}).catch(function(error) {
console.log(error);
});
}
});
# 分享游戏对局回放
# 接口说明
游戏对局回放的分享可以通过使用 sdkInstance.createGameRecorderShareButton(options) (opens new window) 接口创建游戏对局回放分享按钮,并在用户点击时发起。
// 创建分享按钮,并在用户点击时自动跳转至分享页面
sdkInstance.createGameRecorderShareButton(options);
最低基础库版本要求
当用户的客户端基础库版本过低时,调用 sdkInstance.createGameRecorderShareButton(options) 接口将返回 undefined,并在正式版环境下于控制台输出错误提示(非正式版环境下,以弹窗形式展示),需要游戏客户端对返回值做兼容处理!
# 参数说明
参数说明如下表所示:
| 选项 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| type | string | 否 | text | 按钮类型
|
| text | string | 否 | 分享游戏对局回放 | 按钮文本,仅当 type 为 text 时有效 |
| image | string | 否 | -- | 按钮的背景图片,仅当 type 为 image 时有效 |
| style | object | 是 | {} | 按钮样式 |
| style.top | number | 是 | 0 | 按钮左上角纵坐标,单位逻辑像素 |
| style.left | number | 是 | 0 | 按钮左上角横坐标,单位逻辑像素 |
| style.width | number | 否 | 200 | 按钮宽度 |
| style.height | number | 否 | 40 | 按钮高度 |
| style.borderWidth | number | 否 | 0 | 按钮边框宽度 |
| style.borderRadius | number | 否 | 0 | 按钮边框圆角 |
| style.borderColor | string | 否 | #00a1d6 | 按钮边框颜色(hex 颜色代码) |
| style.backgroundColor | string | 否 | #00a1d6 | 按钮背景颜色(hex 颜色代码) |
| style.color | string | 否 | #ffffff | 按钮文本颜色 |
| style.fontSize | number | 否 | 14 | 按钮文本字号 |
| style.textAlign | string | 否 | center | 按钮文本文本水平居中方式
|
| style.lineHeight | number | 否 | 40 | 按钮文本行高 |
| share | object | 是 | -- | 对局回放的分享参数 |
| share.query | object | 否 | -- | 分享时携带的额外参数;点击分享消息进入游戏后,可通过 sdkInstance.launchOptions.query 或调用B站原生方法 bl.getLaunchOptionsSync() 获取该信息 |
| share.timeRange | number[][] | 否 | -- | 对局回放的剪辑区间,是一个二维数组,单位毫秒,如 [[1000, 3000], [4000, 5000]] 表示剪辑已录制对局回放的 1-3 秒和 4-5 秒最终合成为一个 3 秒的对局回放;对局回放剪辑后的总时长最多 60 秒,即 1 分钟 |
| share.bgm | string | 否 | -- | 对局回放背景音乐的地址,必须是代码包文件路径或 blfile:// 文件路径,不支持 http/https 开头的 url |
| share.volume | number | 否 | 1 | 对局回放的音量大小,最小值 0,最大值 1 |
| share.atempo | number | 否 | 1 | 对局回放的播放速率,只能设置以下几个值:0.3、0.5、1、1.5、2、2.5、3;其中1表示原速播放,小于 1 表示减速播放,大于 1 表示加速播放 |
| share.audioMix | boolean | 否 | false | 如果原始视频文件中有音频,是否与新传入的 bgm 混音,默认为 false,表示不混音,只保留一个音轨,值为 true 时表示原始音频与传入的 bgm 混音 |
# 返回值说明
调用 sdkInstance.createGameRecorderShareButton(options) 接口,将返回一个用于分享游戏对局回放的按钮实例。具体实例方法如下表所示:
| 方法 | 类型 | 说明 |
|---|---|---|
| show | function | 用于显示游戏对局回放分享按钮 |
| hide | function | 用于隐藏游戏对局回放分享按钮 |
| destroy | function | 用于销毁游戏对局回放分享按钮 |
| onTap | function | 用于监听分享按钮的点击事件,只有当分享由于非用户取消的原因失败时,该事件的回调函数才会执行 |
| offTap | function | 用于取消监听分享按钮的点击事件 |
# 示例代码
注:示例代码中的参数或选项均为演示数据,仅供参考,谢谢!
// 接上文"录制游戏画面"示例代码
// 创建分享按钮
const gameRecorderShareButton = sdkInstance.createGameRecorderShareButton({
type: "text",
text: "分享游戏对局回放",
style: {
top: 200,
left: 20,
width: 200,
height: 40,
backgroundColor: "#00a1d6",
color: "#ffffff",
fontSize: 14,
textAlign: "center",
lineHeight: 40
},
share: {
query: {
source: "recorder",
scene: "share"
}
}
});
// 先判断 gameRecorderShareButton 是否存在再使用
// 因为当用户的客户端基础库版本过低时,调用 sdkInstance.createGameRecorderShareButton 接口将返回 undefined
if (gameRecorderShareButton) {
// 显示分享按钮
gameRecorderShareButton.show();
// 隐藏分享按钮
gameRecorderShareButton.hide();
// 销毁分享按钮
gameRecorderShareButton.destroy();
// 绑定或注销分享按钮的点击事件回调函数
const listener = function(response) {
console.log(response);
};
gameRecorderShareButton.onTap(listener);
gameRecorderShareButton.offTap(listener);
}