# 游戏对局回放(选接)
游戏对局回放是一组录制游戏画面来生成对局回放,并可以将对局回放分享给朋友的API,收到分享链接的抖音用户可点击链接查看回放,或进入游戏等。
游戏【录屏与分享】 (opens new window)能力是抖音开放平台独有的也是最核心的内容展示及产品分发能力,平台会给上线新游配给一定的冷启动流量作为游戏上线的起始流量,开发者可以通过使用视频录制能力,让游戏发行和平台能力充分结合,在平台内容分发机制的作用下给游戏带来源源不断的后续流量。
注意事项
该能力暂不支持使用抖音开发者工具调试,请使用真机预览测试!
# 录制游戏画面
# 接口说明
用于录制游戏画面来生成对局回放。
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 先判断 gameRecorder 是否存在再使用
// 因为当用户的客户端基础库版本低于 1.6.1 时,调用 sdkInstance.getGameRecorder 接口将返回 undefined
if (gameRecorder) {
// 监听录制开始事件,当对应事件触发时,回调函数会被执行
gameRecorder.onStart(callback);
// 监听录制暂停事件,当对应事件触发时,回调函数会被执行
gameRecorder.onPause(callback);
// 监听录制恢复事件,当对应事件触发时,回调函数会被执行
gameRecorder.onResume(callback);
// 监听录制结束事件,当对应事件触发时,回调函数会被执行
gameRecorder.onStop(callback);
// 监听录制中断开始事件,当对应事件触发时,回调函数会被执行
gameRecorder.onInterruptionBegin(callback);
// 监听录制中断结束事件,当对应事件触发时,回调函数会被执行
gameRecorder.onInterruptionEnd(callback);
// 监听录制错误事件,当对应事件触发时,回调函数会被执行
gameRecorder.onError(callback);
// 开始录制游戏画面,可以通过 onStart 接口监听录制开始事件
gameRecorder.start(options);
// 暂停录制游戏画面,可以通过 onPause 接口监听录制暂停事件
gameRecorder.pause();
// 恢复录制游戏画面,可以通过 onResume 接口监听录制恢复事件
gameRecorder.resume();
// 结束录制游戏画面,可以通过 onStop 接口监听录制结束事件,获得录制的视频地址
gameRecorder.stop();
// 记录精彩的视频片段,调用时必须是正在录制,以调用时的录制时刻为基准,指定前 x 秒,后 y 秒为将要裁剪的片段,可以多次调用,记录不同时刻;在结束录制时,可以调用 clipVideo 接口剪辑并合成记录的片段
gameRecorder.recordClip(options);
// 剪辑精彩的视频片段
gameRecorder.clipVideo(options);
// 获取水印宽高,开发者可以通过宽高计算水印添加的位置
gameRecorder.getMark();
}
// 不存在或不支持录制时,弹出相应提示
else {
sdkInstance.modal.message("暂不支持此功能");
}
最低基础库版本要求
若用户客户端基础库版本低于 1.6.1
,调用 sdkInstance.getGameRecorder()
接口将返回 undefined
,并在正式版环境下于控制台输出错误提示(非正式版环境下,以弹窗形式展示),需要游戏客户端对返回值做兼容处理!
# 录制器
调用接口 sdkInstance.getGameRecorder() (opens new window) 将返回一个全局单例录制器 GameRecorder (opens new window)。录制游戏画面是一项比较消耗性能的能力,在某些系统、设备上无法进行游戏画面录制,因此在调用游戏画面录制能力前,需先判断当前环境是否支持该能力,如下所示:
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 判断是否支持录制游戏画面
if (gameRecorder) {
// 若支持,再执行后续相关操作
// ......
}
// 不存在或不支持录制时,弹出相应提示
else {
sdkInstance.modal.message("暂不支持此功能");
}
所有和录制有关的API都挂载在 GameRecorder (opens new window) 对象上:
- GameRecorder.onStart(callback) (opens new window) 监听录制开始事件
- GameRecorder.onPause(callback) (opens new window) 监听录制暂停事件
- GameRecorder.onResume(callback) (opens new window) 监听录制恢复事件
- GameRecorder.onStop(callback) (opens new window) 监听结束事件事件,可在回调函数中获得录制的视频地址
- GameRecorder.onInterruptionBegin(callback) (opens new window) 监听录制中断开始事件
- GameRecorder.onInterruptionEnd(callback) (opens new window) 监听录制中断结束事件
- GameRecorder.onError(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.recordClip(options) (opens new window) 记录精彩的视频片段
- GameRecorder.clipVideo(options) (opens new window) 剪辑精彩的视频片段
- GameRecorder.getMark() (opens new window) 获取水印宽高,开发者可以通过宽高计算水印添加的位置
调用 GameRecorder.start(options) (opens new window) 开始录制,调用 GameRecorder.stop() (opens new window) 结束录制:
// 监听录制开始事件,回调函数被执行时表示录制已开始
gameRecorder.onStart(function(result) {
// 真正开始录制 5 秒后结束录制
setTimeout(function() {
gameRecorder.stop();
}, 5000);
});
// 监听录制结束事件,回调函数被执行时表示录制已完成
gameRecorder.onStop(function(result) {
// 回调函数中可获得录制的视频地址
console.log(result.videoPath);
});
// 开始录制
gameRecorder.start();
如果在录制过程中有玩家思考等待等过程,可以调用 GameRecorder.pause() (opens new window) 暂停录制,然后再用 GameRecorder.resume() (opens new window) 恢复录制:
// 监听录制暂停事件,回调函数被执行时表示录制已暂停
gameRecorder.onPause(function(result) {
// 真正开始暂停 5 秒后恢复录制
setTimeout(function() {
gameRecorder.resume();
}, 5000);
});
// 监听录制恢复事件,回调函数被执行时表示录制已恢复
gameRecorder.onResume(function(result) {
console.log("录制已恢复");
});
// 暂停录制
gameRecorder.pause();
# 监听录制开始事件
GameRecorder.onStart(callback) (opens new window) 用于监听录制开始事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
# 监听录制暂停事件
GameRecorder.onPause(callback) (opens new window) 用于监听录制暂停事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
# 监听录制恢复事件
GameRecorder.onResume(callback) (opens new window) 用于监听录制恢复事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
# 监听录制结束事件
GameRecorder.onStop(callback) (opens new window) 用于监听录制结束事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行,可在回调函数中获得录制的视频地址;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
回调函数 callback
会接收一个 object
类型参数,属性说明如下表所示:
选项 | 类型 | 说明 |
---|---|---|
videoPath | string | 录屏文件的临时路径 |
# 监听录制中断开始事件
GameRecorder.onInterruptionBegin(callback) (opens new window) 用于监听录制中断开始事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
# 监听录制中断结束事件
GameRecorder.onInterruptionEnd(callback) (opens new window) 用于监听录制中断结束事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
# 监听录制错误事件
GameRecorder.onError(callback) (opens new window) 用于监听录制错误事件,包含 callback
一个参数,当对应事件触发时,回调函数会被执行,可在回调函数中获得相应的错误信息;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
callback | function | 是 | -- | 事件触发时执行的回调函数 |
回调函数 callback
会接收一个 object
类型参数,属性说明如下表所示:
选项 | 类型 | 说明 |
---|---|---|
errMsg | string | 录屏的错误信息 |
# 开始录制
GameRecorder.start(options) (opens new window) 用于开始录制游戏画面;参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
duration | number | 否 | 10 | 视频时长限制,单位为秒;最小值 3 ,最大值 300 ,到达指定时长后不会再录制,但仍然需要手动调用 GameRecorder.stop() 来结束录制 |
isMarkOpen | boolean | 否 | true | 是否添加水印,会在录制出来的视频上添加默认水印,目前不支持自定义水印图案;用户客户端基础库版本不低于 1.69.0 时支持 |
locTop | number | 否 | 0 | 水印距离屏幕上边界的位置,单位为 dp ;用户客户端基础库版本不低于 1.69.0 时支持 |
locLeft | number | 否 | 0 | 水印距离屏幕左边界的位置,单位为 dp ;用户客户端基础库版本不低于 1.69.0 时支持 |
frameRate | number | 否 | 30 | 设置录制帧率,对于性能较差的手机可以调低参数以降低录制性能消耗;用户客户端基础库版本不低于 1.80.0 时支持 |
# 暂停录制
GameRecorder.pause() (opens new window) 用于暂停录制游戏画面。
# 恢复录制
GameRecorder.resume() (opens new window) 用于恢复录制游戏画面。
# 结束录制
GameRecorder.stop() (opens new window) 用于结束录制游戏画面。
# 记录精彩的视频片段
GameRecorder.recordClip(options) (opens new window) 用于记录精彩的视频片段,调用时必须是正在录制,以调用时的录制时刻为基准,指定前 x
秒,后 y
秒为将要裁剪的片段,可以多次调用,记录不同时刻;在结束录制时,可以调用 GameRecorder.clipVideo(options) (opens new window) 接口剪辑并合成记录的片段;参数说明如下所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
timeRange | array | 否 | [3, 3] | 数组的值表示记录这一时刻的前后时间段内的视频,单位为秒 |
success | function | 否 | -- | 接口调用成功的回调函数;用户客户端基础库版本不低于 1.20.0 时支持 |
fail | function | 否 | -- | 接口调用失败的回调函数;用户客户端基础库版本不低于 1.20.0 时支持 |
complete | function | 否 | -- | 接口调用完成的回调函数,成功或失败均会调用;用户客户端基础库版本不低于 1.20.0 时支持 |
回调函数 success
会接收一个 object
类型参数,属性说明如下表所示:
选项 | 类型 | 说明 |
---|---|---|
index | number | 裁剪片段的唯一索引,用于 GameRecorder.clipVideo(options) 接口调用时指定裁剪拼接顺序 |
# 剪辑精彩的视频片段
GameRecorder.clipVideo(options) (opens new window) 用于剪辑精彩的视频片段;参数说明如下所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
path | string | 是 | -- | 结束录制时获得的视频地址 |
timeRange | array | 否 | -- | 裁剪的范围,用法含义与 GameRecorder.recordClip(options) 接口中的 timeRange 完全相同,只是记录时相对的当前时刻规定为录制结束时刻;用户客户端基础库版本不低于 1.13.9 时支持 |
clipRange | array | 否 | -- | 指定要裁剪的范围,数组中每一项为调用 GameRecorder.recordClip(options) 接口得到返回值;用户客户端基础库版本不低于 1.20.0 时支持 |
success | function | 否 | -- | 接口调用成功的回调函数 |
fail | function | 否 | -- | 接口调用失败的回调函数 |
complete | function | 否 | -- | 接口调用完成的回调函数,成功或失败均会调用 |
注意事项
- 若不传
clipRange
字段,会按照默认的 GameRecorder.recordClip(options) (opens new window) 的调用顺序裁剪视频并合并,对于 GameRecorder.recordClip(options) (opens new window) 调用时timeRange
字段可能产生交集的部分会自动合并,确保生成的视频内容是无重复且顺序符合记录顺序; - 若指定了
clipRange
字段,平台将只会按clipRange
数据的顺序裁剪合并视频,并对于重复的部分不做处理,开发者可利用该功能实现自定义裁剪片段、自定义拼接顺序(若同时指定了timeRange
,该片段将依旧作为最后一段拼接),对于最终视频可能出现的重复内容,需要开发者自己保证; - 若指定了
clipRange
字段,需要保证clipRange
参数的长度需要大于1
。在同时指定了timeRange
的情况下,timeRange
参数会在内部生成为 GameRecorder.recordClip(options) (opens new window) 得到返回值 ,并加入到clipRange
数组中,即timeRange
会在内部转换为clipRange
数组的一项追加到数组末尾。
回调函数 success
会接收一个 object
类型参数,属性说明如下表所示:
属性 | 类型 | 说明 |
---|---|---|
videoPath | string | 剪辑的视频地址 |
# 获取水印宽高
GameRecorder.getMark() (opens new window) 用于获取录制时的水印宽高,开发者可以通过宽高计算水印添加的位置;返回值说明如下表所示:
属性 | 类型 | 说明 |
---|---|---|
markWidth | number | 水印的宽度;用户客户端基础库版本不低于 1.69.0 时支持 |
markHeight | number | 水印的高度;用户客户端基础库版本不低于 1.69.0 时支持 |
# 示例代码
注:示例代码中的参数或选项均为演示数据,仅供参考,谢谢!
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 判断 gameRecorder 是否存在再使用,若存在且支持录制,则优先注册好相关的事件监听
// 因为当用户的客户端基础库版本低于 1.6.1 时,调用 sdkInstance.getGameRecorder 接口将返回 undefined
if (gameRecorder) {
// 监听录制开始事件
gameRecorder.onStart(function(result) {
sdkInstance.modal.message("录制已开始");
});
// 监听录制暂停事件
gameRecorder.onPause(function(result) {
sdkInstance.modal.message("录制已暂停");
});
// 监听录制恢复事件
gameRecorder.onResume(function(result) {
sdkInstance.modal.message("录制已恢复");
});
// 监听录制结束事件
gameRecorder.onStop(function(result) {
sdkInstance.modal.message("录制已结束");
});
// 监听录制中断开始事件,当对应事件触发时,回调函数会被执行,详见下文说明
gameRecorder.onInterruptionBegin(function(result) {
sdkInstance.modal.message("录制中断开始");
});
// 监听录制中断结束事件,当对应事件触发时,回调函数会被执行,详见下文说明
gameRecorder.onInterruptionEnd(function(result) {
sdkInstance.modal.message("录制中断结束");
});
// 监听录制错误事件,当对应事件触发时,回调函数会被执行,详见下文说明
gameRecorder.onError(function(result) {
sdkInstance.modal.message(result.errMsg);
});
}
// 绘制"开始录制"按钮,并在点击时调用 gameRecorder.start() 开始录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "开始录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 开始录制
gameRecorder.start({
duration: 180
});
}
});
// 绘制"结束录制"按钮,并在点击时调用 gameRecorder.stop() 结束录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "结束录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 结束录制
gameRecorder.stop();
}
});
# 分享游戏对局回放
# 接口说明
用于分享生成的游戏对局回放。
sdkInstance.shareGameRecorderVideo(options);
# 参数说明
参数说明如下表所示:
选项 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
templateId | string | 否 | -- | 分享文案模板ID,通过指定该参数来选择分享文案,文案内容需在抖音开放平台设置且通过审核 |
title | string | 否 | -- | 分享时显示的标题 |
desc | string | 否 | -- | 分享时显示的描述文案 |
query | object | 否 | -- | 分享时携带的额外参数;点击分享消息进入游戏后,可通过 sdkInstance.launchOptions.query 或调用抖音原生方法 tt.getLaunchOptionsSync() 获取该信息 |
videoTitle | string | 否 | -- | 默认的输入文案 |
videoPath | string | 是 | -- | 视频地址,分享一个本地视频;其值可在 GameRecorder.onStop(callback) 录制结束事件的回调函数中获取 |
videoTopics | string[] | 否 | -- | 视频话题,字符串中间包含空格会取第一个空格前的内容作为话题(仅抖音支持) |
videoTag | string | 否 | -- | 视频标签,可以结合获取抖音视频排行榜使用 |
videoBgm | string | 否 | -- | 抖音PGC音乐的短链(仅抖音支持,需要基础库版本大于 1.90.0 ),形如https://v.douyin.com/JmcxWo8/,参考抖音小游戏录屏带配乐能力 |
success | function | 否 | -- | 接口调用成功的回调函数 |
fail | function | 否 | -- | 接口调用失败的回调函数 |
complete | function | 否 | -- | 接口调用完成的回调函数,成功或失败均会调用 |
# 示例代码
注:示例代码中的参数或选项均为演示数据,仅供参考,谢谢!
// 创建并返回一个全局单例录制器
const gameRecorder = sdkInstance.getGameRecorder();
// 用于临时存放录制好的视频地址
let videoPath = "";
// 判断 gameRecorder 是否存在再使用,若存在且支持录制,则优先注册好相关的事件监听
// 因为当用户的客户端基础库版本低于 1.6.1 时,调用 sdkInstance.getGameRecorder 接口将返回 undefined
if (gameRecorder) {
// 监听录制开始事件
gameRecorder.onStart(function(result) {
sdkInstance.modal.message("录制已开始");
});
// 监听录制结束事件
gameRecorder.onStop(function(result) {
videoPath = result.videoPath;
sdkInstance.modal.message("录制已结束");
});
// 监听录制错误事件,当对应事件触发时,回调函数会被执行,详见下文说明
gameRecorder.onError(function(result) {
sdkInstance.modal.message(result.errMsg);
});
}
// 绘制"开始录制"按钮,并在点击时调用 gameRecorder.start() 开始录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "开始录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 开始录制
gameRecorder.start({
duration: 180
});
}
});
// 绘制"结束录制"按钮,并在点击时调用 gameRecorder.stop() 结束录制
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "结束录制",
handler: function() {
// 检查是否支持录制游戏画面
if (!gameRecorder) {
return sdkInstance.modal.message("暂不支持此功能");
}
// 结束录制
gameRecorder.stop();
}
});
// 绘制"分享游戏对局回放"按钮,并在点击时调用 sdkInstance.shareGameRecorderVideo(options) 时分享游戏对局回放
// 此处 addButton 仅为演示,实际按钮的创建与点击事件回调函数由开发者自行使用游戏引擎实现
addButton({
text: "分享游戏对局回放",
handler: function() {
// 判断是否存在录制好的视频
if (!videoPath) {
sdkInstance.modal.message("暂无可分享视频");
}
// 分享游戏对局回放
sdkInstance.shareGameRecorderVideo({
title: "录屏示例",
desc: "这是抖音小游戏录屏功能的演示示例",
query: {
param1: 1,
param2: 2
},
videoTitle: "是兄弟,就来砍我!",
videoPath: videoPath,
videoTopics: ["游戏", "仙侠"],
videoTag: "最新",
videoBgm: "https://v.douyin.com/JmcxWo8/",
success: function(response) {
console.log(response);
},
fail: function(error) {
console.log(error);
sdkInstance.modal.message(error.message);
},
complete: function() {
// do something here...
}
});
}
});