### Example: Start and Stop Recording with Event Handling
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/record/recorder-manager/recorder-manager-off-stop
This example shows how to start and stop recording, including setting up and tearing down the 'onStop' event listener. It ensures that the listener is only attached if it doesn't already exist and is properly removed when the page unloads.
```javascript
Page({
data: {
status: "暂未开始",
},
// onStop时绑定的事件处理函数
onStopCallback: null,
onUnload() {
this.recorderManager && this.recorderManager.offStop();
this.onStopCallback = null;
},
startRecord() {
this.recorderManager = tt.getRecorderManager();
const options = {
duration: 60000,
sampleRate: 12000,
numberOfChannels: 1,
encodeBitRate: 25000,
frameSize: 100,
};
// 如果目前没有绑定onStop的事件处理函数才能够绑定
if (!onStopCallback) {
this.onStopCallback = (res) => {
tt.showModal({
title: "录音结束",
content: JSON.stringify(res),
});
this.setData({
status: "录音结束",
});
};
this.recorderManager.onStop(this.onStopCallback);
}
this.recorderManager.start(options);
tt.showToast({ title: "点击了开始录音" });
this.setData({
status: "正在录音",
});
},
stopRecord() {
this.recorderManager && this.recorderManager.stop();
},
});
```
--------------------------------
### Go SDK Package Installation
Source: https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/sdk-overview
Install the Go SDK package using the go get command.
```bash
go get github.com/bytedance/douyin-openapi-sdk-go
```
--------------------------------
### MediaRecorder Initialization and Start Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/canvas-recording/media-recorder/media-recorder-start
This example demonstrates how to initialize a MediaRecorder with a canvas context and then start the recording. Ensure the canvas element is present in the WXML and the recorder is initialized in the Page's onReady lifecycle.
```html
```
```javascript
Page({
async onReady() {
this.videoContext = tt.createVideoContext("myVideo");
tt.createSelectorQuery()
.select("#myCanvas")
.node()
.exec((res) => {
// 获取 canvas 实例
const canvas = res[0].node;
const canvasCtx = canvas.getContext("2d");
this.recorder = tt.createMediaRecorder(canvas, {
width: canvas.width, // video width
height: canvas.height, // video height
videoBitsPerSecond: 1000, // bit rate in kbps
gop: 12, // key frame interval
fps: 60, // frames per second
});
});
},
start() {
this.recorder.start();
tt.showToast({
title: "start",
icon: "none",
});
},
});
```
--------------------------------
### RecorderManager.onStart Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/record/recorder-manager/recorder-manager-on-start
This example demonstrates how to use RecorderManager.onStart to listen for the recording start event. It also includes handlers for pause, resume, and stop events, along with a countdown timer. Ensure tt.getRecorderManager() is called to get the recorder instance.
```javascript
const countdown = 6000;
let cdtimer = null;
Page({
data: {
cd: countdown,
isStart: false,
isPlay: false,
options: {
duration: countdown,
sampleRate: 12000,
numberOfChannels: 1,
encodeBitRate: 25000,
frameSize: 100,
}
},
onLoad() {
this.recorderManager = tt.getRecorderManager();
// 监听录音开始事件
this.recorderManager.onStart(() => {
this.setData({
isStart: true,
isPlay: true,
cd: countdown
});
this.startCountDown();
tt.showToast({
title: '录音开始了'
});
});
// 监听录音暂停事件
this.recorderManager.onPause(() => {
this.setData({
isPlay: false
});
clearInterval(cdtimer);
console.log("已暂停录音");
});
// 监听录音继续事件
this.recorderManager.onResume(() => {
this.setData({
isPlay: true
});
this.startCountDown();
console.log("已继续录音");
});
// 监听录音停止事件
this.recorderManager.onStop((res) => {
clearInterval(cdtimer);
this.setData({
isStart: false,
isPlay: false,
cd: countdown
});
console.log("已停止录音,录音文件的地址为: ", res.tempFilePath);
});
},
onUnload: function () {
this.stop();
},
start() {
this.recorderManager.start(this.data.options);
},
stop() {
// 停止录音
this.recorderManager.stop();
},
pause() {
// 暂停录音
this.recorderManager.pause();
},
resume() {
// 继续录音
this.recorderManager.resume();
},
startCountDown() {
clearInterval(cdtimer);
cdtimer = setInterval(() => {
this.setData({
cd: this.data.cd - 100
});
}, 100);
}
})
```
--------------------------------
### FileSystemManager.rmdirSync Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/file/file-system-manager/file-system-manager-rmdir-sync
This example demonstrates how to create a directory using mkdirSync and then delete it using rmdirSync. Ensure the directory path starts with 'ttfile://user'.
```javascript
const fileSystemManager = tt.getFileSystemManager()
// 必须以 "ttfile://user" 开头
const exmaplePath = "ttfile://user/example-dir"
try {
fileSystemManager.mkdirSync(exmaplePath)
console.log("成功")
} catch (err) {
console.log("失败", err)
}
try {
fileSystemManager.rmdirSync(exmaplePath, false)
console.log("成功")
} catch (err) {
console.log("失败", err)
}
```
--------------------------------
### FileSystemManager.copyFileSync Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/file/file-system-manager/file-system-manager-copy-file-sync
This example demonstrates how to download a network resource and then synchronously copy it to the user's directory using FileSystemManager.copyFileSync. Ensure the destination path starts with `ttfile://user`.
```javascript
const fileSystemManager = tt.getFileSystemManager()
// Download network resource
tt.downloadFile({
url: "https://s3.pstatp.com/toutiao/resource/developer/static/img/main-logo.8e3a839.png",
success(res) {
console.log("Download successful", res.tempFilePath)
try {
// Copy file, destPath directory must start with `ttfile://user`
fileSystemManager.copyFileSync(res.tempFilePath, `ttfile://user/logo.png`)
console.log("Copy successful")
} catch (err) {
console.log("Copy failed", err)
}
},
fail(res) {
console.log("Download failed", res.errMsg)
},
})
```
--------------------------------
### Immediate Purchase Example (Non-Goods Library)
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/component/industry/trading-system/pay-button-sdk
This example configures the pay-button for immediate purchase of non-goods library items. It specifies mode 2, goods-type 2, and binds functions for getting goods info, placing an order, and payment.
```html
```
--------------------------------
### Get Launch Options Sync Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/open-ability/feed/minigame-feedpush-setting-guide
This example demonstrates how to use the `tt.getLaunchOptionsSync` API to retrieve launch options, specifically checking if the launch scene is related to the recommendation feed for direct play. It also shows how to report pre-boot data.
```javascript
JS API:tt.getLaunchOptionsSyncC# API:TT.GetLaunchOptionsSync| scene| string| xx3041| 用于判断是否为推荐流直玩场景(xx为可变的数字,判断后四位是 3041 即可确认为推荐流直玩)| ```
{
"scene": "023041"
"query": {
"feed_game_scene": 1,
"feed_game_extra": "",
"feed_game_content_id": "CONTENTxxx",
"feed_game_channel": 1
}
}
```
query| feed_game_scene| number| 1| 离线收益场景
2| 体力恢复场景
3| 重要事件掉落
feed_game_extra| string| 自定义| 开发者自定义字段,可通过 推荐流直玩能力 OpenAPI 接入文档 接口的 extra 字段进行赋值
feed_game_content_id| string| 平台生成| 本次启动对应的文案 ID|
feed_game_channel| number| 1| 复访用户|
2| 获客用户|
```
--------------------------------
### Get Mark Dimensions and Start Recording
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/screen-recording/game-recorder-manager/game-recorder-manager-get-mark
This example demonstrates how to get the screen recording watermark dimensions using `recorder.getMark()` and then use these dimensions to center the watermark when starting the recording with `recorder.start()`. It requires obtaining system screen information first.
```javascript
tt.getSystemInfo({
success(res) {
const screenWidth = res.screenWidth;
const screenHeight = res.screenHeight;
const recorder = tt.getGameRecorderManager();
var maskInfo = recorder.getMark(); //获取水印的宽高
var x = (screenWidth - maskInfo.markWidth) / 2;
var y = (screenHeight - maskInfo.markHeight) / 2;
recorder.onStart((res) => {
console.log("录屏开始");
// do something;
});
//添加水印并且居中处理
recorder.start({
duration: 30,
isMarkOpen: true,
locLeft: x,
locTop: y,
});
},
});
```
--------------------------------
### FileSystemManager.mkdirSync Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/file/file-system-manager/file-system-manager-mkdir-sync
This example demonstrates how to synchronously create a directory, including its parent directories if they don't exist. It uses a try-catch block to handle potential errors during the directory creation process.
```javascript
const fileSystemManager = tt.getFileSystemManager()
try {
fileSystemManager.mkdirSync("ttfile://user/some/path", true)
console.log("调用成功")
} catch (err) {
console.log("调用失败", err)
}
```
--------------------------------
### NodeJS SDK Example: Get User Message
Source: https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/sdk-overview
Example of using the NodeJS SDK to get user messages. Demonstrates obtaining an access token and making an API call.
```javascript
import Client, { MessageGetUserMessageRequest } from '@open-dy/open_api_sdk';
import CredentialClient from '@open-dy/open_api_credential';
interface ClientTokenResponse {
data?: {
access_token?: string,
description?: string,
error_code?: number,
expires_in?: number
}
}
// 传入 clientKey 和 clientSecret 获取 token
const credentialClient = new CredentialClient({clientKey: 'xxx', clientSecret: 'xxx'});
const { accessToken } = await credentialClient.getClientToken();
// 传入 clientKey 和 clientSecret
const client = new Client({ clientKey: 'xxx', clientSecret: 'xxx' });
// 拼接请求入参
const params = new MessageGetUserMessageRequest({accessToken:accessToken, startTime:xxx, endTime: xxx, type: xxx, username: xxx, pageNum: xxx, pageSize: xxx });
// 调用方法发起请求
const messageRes = await client.messageGetUserMessage(params);
console.log('messageRes', messageRes);
```
--------------------------------
### Code Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/record/recorder-manager/recorder-manager-start
Example of how to use the RecorderManager.start method in a mini-program.
```javascript
const countdown = 6000;
let cdtimer = null;
Page({
data: {
cd: countdown,
isStart: false,
options: {
duration: countdown,
sampleRate: 12000,
numberOfChannels: 1,
encodeBitRate: 25000,
frameSize: 100,
}
},
onLoad() {
this.recorderManager = tt.getRecorderManager();
this.recorderManager.onStart(() => {
this.setData({
isStart: true,
cd: countdown
});
this.startCountDown();
});
// Listen for recording stop event
this.recorderManager.onStop((res) => {
clearInterval(cdtimer);
this.setData({
isStart: false,
cd: countdown
});
});
},
onUnload: function () {
this.stop();
},
start() {
this.recorderManager.start(this.data.options);
},
stop() {
// Stop recording
this.recorderManager.stop();
},
startCountDown() {
clearInterval(cdtimer);
cdtimer = setInterval(() => {
this.setData({
cd: this.data.cd - 100
});
}, 100);
}
})
```
--------------------------------
### Basic Usage Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/industry-plugin/e-commerce-plugin/components/productfollowbutton
A simple example demonstrating how to use the product-follow-button component with essential properties and event handlers.
```APIDOC
## Basic Usage Example
### Description
This example shows a basic implementation of the `product-follow-button` component, including setting the shop and product IDs, and attaching event listeners for follow, unfollow, and error events.
### Code Example
```html
```
```
--------------------------------
### CameraFrameListener.start Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/camera/camera-frame-listener/camera-frame-listener-start
This example demonstrates how to start listening for camera frame data. It requires camera authorization and uses CameraContext.onCameraFrame to receive frame details. Ensure frame-size and resolution are consistent to avoid image stretching. Developer tools do not support this feature; use a real device for debugging.
```html
第 {{counter}} 帧
frameWidth{{frameWidth}}; frameHeight:{{frameHeight}}
```
```javascript
var listener;
Page({
data: {
counter: 0,
frameWidth: 0,
frameHeight: 0,
},
onLoad: function (options) {
this.openCamera();
},
openCamera() {
tt.getSetting({
success: (res) => {
let cameraAllowed = res.authSetting["scope.camera"];
if (cameraAllowed) {
this.ctx = tt.createCameraContext();
} else {
tt.showToast({
title: "请授权相机后重新进入"
});
}
},
fail: (err) => {
tt.showModal({
title: "获取授权失败",
content: JSON.stringify(err),
});
},
});
},
startOnFrame(e) {
listener = this.ctx.onCameraFrame((frame) => {
let { width, height, data } = frame;
this.setData({
counter: this.data.counter + 1,
frameWidth: width,
frameHeight: height,
});
});
listener.start({
success: (res) => {
tt.showToast({ title: "开始接收帧数据" });
},
fail: (err) => {
tt.showModal({
title: "接收失败",
content: JSON.stringify(err),
});
},
});
},
onError(err) {
tt.showModal({
title: "相机出错了",
content: JSON.stringify(err),
});
},
});
```
--------------------------------
### RecorderManager Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/record/recorder-manager/recorder-manager-pause
This example demonstrates how to use RecorderManager methods, including pause, start, resume, and stop, within a mini-program. It includes event listeners for recording start, pause, resume, and stop events, along with a countdown timer.
```html
剩余录音时间 {{ cd }}ms
```
```javascript
const countdown = 6000;
let cdtimer = null;
Page({
data: {
cd: countdown,
isStart: false,
isPlay: false,
options: {
duration: countdown,
sampleRate: 12000,
numberOfChannels: 1,
encodeBitRate: 25000,
frameSize: 100,
}
},
onLoad() {
this.recorderManager = tt.getRecorderManager();
// 监听录音开始事件
this.recorderManager.onStart(() => {
this.setData({
isStart: true,
isPlay: true,
cd: countdown
});
this.startCountDown();
});
// 监听录音暂停事件
this.recorderManager.onPause(() => {
this.setData({
isPlay: false
});
clearInterval(cdtimer);
console.log("已暂停录音");
});
// 监听录音继续事件
this.recorderManager.onResume(() => {
this.setData({
isPlay: true
});
this.startCountDown();
console.log("已继续录音");
});
// 监听录音停止事件
this.recorderManager.onStop((res) => {
clearInterval(cdtimer);
this.setData({
isStart: false,
isPlay: false,
cd: countdown
});
console.log("已停止录音,录音文件的地址为: ", res.tempFilePath);
});
},
onUnload: function () {
this.stop();
},
start() {
this.recorderManager.start(this.data.options);
},
stop() {
// 停止录音
this.recorderManager.stop();
},
pause() {
// 暂停录音
this.recorderManager.pause();
},
resume() {
// 继续录音
this.recorderManager.resume();
},
startCountDown() {
clearInterval(cdtimer);
cdtimer = setInterval(() => {
this.setData({
cd: this.data.cd - 100
});
}, 100);
}
})
```
--------------------------------
### CameraContext.startRecord Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/camera/camera-context/camera-context-start-record
This example demonstrates how to use CameraContext.startRecord to begin video recording and CameraContext.stopRecord to end it. It also shows how to display the recorded video. Note that the developer tools do not support this capability; use a real device for debugging.
```html
录像结果
```
```javascript
Page({
data: {
src: "",
},
onLoad: function (options) {
tt.getSetting({
success: (res) => {
let cameraAllowed = res.authSetting["scope.camera"];
if (!cameraAllowed) {
tt.showToast({
title: "请授权相机后重新进入", // 内容
});
}
},
fail: (err) => {
tt.showModal({
title: "获取授权失败",
content: JSON.stringify(err),
});
},
});
},
startRecord() {
if (!this.ctx) {
this.ctx = tt.createCameraContext();
}
this.ctx.startRecord({
timeoutCallback: (res) => {
console.log("timeoutCallback", res);
this.setData({
src: res.tempVideoPath,
});
},
success: (res) => {
console.log("success", res);
},
fail(err) {
console.log("fail", err);
},
});
},
stopRecord() {
if (!this.ctx) {
this.ctx = tt.createCameraContext();
}
this.ctx.stopRecord({
compressed: true,
success: (res) => {
console.log("success", res);
this.setData({
src: res.tempVideoPath,
});
},
fail(err) {
console.log("fail", err);
},
});
},
});
```
--------------------------------
### Get User Follow List Request Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-management/user-data/get-user-follow-list
This example demonstrates how to make a GET request to the following list API. Ensure you include the necessary headers like 'content-type' and 'access-token', along with query parameters such as 'open_id', 'cursor', and 'count'.
```curl
curl --location --request GET 'https://open.douyin.com/following/list/?open_id=ba253642-0590-40bc-9bdf-9a1334b94059&cursor=8220143259583580345&count=6263770607887403045' \
--header 'content-type: application/json' \
--header 'access-token: 0801121846735352506a356a6' \
```
--------------------------------
### Get Mini-Program Launch Options
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/foundation/lifecycle/tt-get-enter-options-sync
Call tt.getEnterOptionsSync() to retrieve the parameters associated with the current mini-program launch. This is useful for understanding how the mini-program was started, whether by a cold start or a hot start.
```javascript
tt.getEnterOptionsSync()
```
--------------------------------
### FileSystemManager.readdirSync Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/file/file-system-manager/file-system-manager-readdir-sync
This example demonstrates how to use FileSystemManager.readdirSync to get a list of files in a directory. Ensure the directory path is correct and accessible.
```javascript
const fsm = tt.getFileSystemManager();
try {
const files = fsm.readdirSync('/path/to/directory');
console.log('Files in directory:', files);
} catch (e) {
console.error('Error reading directory:', e);
}
```
--------------------------------
### Create Order for Pre-orderable Goods (Instant Reservation)
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/industry-plugin/life-service-plugin/pre-order/plugin-create-order
This example demonstrates how to create an order for pre-orderable goods using the `createOrder` method with `skuType: 1`. It includes details for `skuList`, `bookInfo`, `payment`, `contactInfo`, `storeInfo`, `callbackData`, and `tradeOption`. The `success` and `fail` callbacks handle the order processing results.
```APIDOC
## Create Order for Pre-orderable Goods (Instant Reservation)
This example demonstrates how to create an order for pre-orderable goods using the `createOrder` method with `skuType: 1`. It includes details for `skuList`, `bookInfo`, `payment`, `contactInfo`, `storeInfo`, `callbackData`, and `tradeOption`. The `success` and `fail` callbacks handle the order processing results.
```javascript
const plugin = tt.requirePlugin('tta5a3d31e3aecfb9b11');
plugin.createOrder({
skuList: [
{
skuId: "xxx", // sku 商品Id 必传
skuType: 1, // sku 商品类型 必传
quantity: 10, // 数量 必传
price: 1, // 价格 预约 商品必传
goodsInfo: {
goodsName: "预约商品", // 商品名称 必填
goodsPhoto:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.ibaotu.com%2Fgif%2F19%2F48%2F47%2F76Z888piCd6W.gif%21fwpaa50%2Ffw%2F700&refer=http%3A%2F%2Fpic.ibaotu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644654365&t=5fc9b5fdad0a16264a9a9c09c14b3af9", // 商品图片链接 必填
goodsId: "123", // 商品ID 必填(请务必使用小程序商品)
goodsType: 1, // 商品类型 必填
goodsLabels: ["不可退"], // 商品标签 非必填
dateRule: "", // 使用规则 非必填
},
extraInfo: {
ticketName: "child", // 票种,非商品库门票类 sku 必传
date: "2022-07-26", // 日期,非商品库门票类 sku 必传
},
},
],
bookInfo: {
itemBookInfoList: [
{
poiId: "12313131331", // 预约门店的 poiId,必填
shopName: "测试名称", // 预约店铺名称,必填
outShopId: "11121234434", // 预约门店的外部店铺id,必填
goodsId: "123", // 商品id,必填
bookStartTime: new Date(2022, 7, 25).getTime(), // 预定开始时间(ms),13位毫秒时间戳,必填
bookEndTime: new Date(2022, 7, 26).getTime(), //预定结束时间(ms),13位毫秒时间戳,必填
},
],
},
payment: {
totalAmount: 10, // 订单总价 必填
},
contactInfo: {
phoneNumber: "12345678901", // 手机号 非必传
contactName: "test name", // 姓名 非必传
},
note: "for future", // 备注 非必传
storeInfo: {
storeName: "test store", // 商店名称 非必传
storeIcon:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.ibaotu.com%2Fgif%2F19%2F48%2F47%2F76Z888piCd6W.gif%21fwpaa50%2Ffw%2F700&refer=http%3A%2F%2Fpic.ibaotu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644654365&t=5fc9b5fdad0a16264a9a9c09c14b3af9", // 商店头像 非必填
},
callbackData: { test: 999999 }, // 透传数据,开发者自定义字段 非必传
tradeOption:{
life_trade_flag :0 // 0:非融合链路(默认值) 1:走融合链路(标准融合/完全融合/预约品下单必传)
}, // 透传数据,开发者自定义字段 非必传
success: (res) => {
const { orderId, outOrderNo } = res;
console.log("success res", res);
console.log("orderId", orderId, "outOrderNo", outOrderNo);
this.setData({ orderId, outOrderNo });
},
fail: (res) => {
const { orderId, outOrderNo, errNo, errMsg, errLogId } = res;
if (errLogId) {
console.log("预下单失败", errNo, errMsg, errLogId);
}
if (orderId || outOrderNo) {
console.log("支付失败", errNo, errMsg, orderId, outOrderNo);
}
console.log(errNo, errMsg);
},
});
```
```
--------------------------------
### Camera Component Usage Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/component/media-component/camera
Example demonstrating how to use the Camera component in a mini-program, including basic setup and event handling.
```APIDOC
// index.js
Page({
data: {},
onLoad: function (options) {
tt.getSetting({
success: (res) => {
let cameraAllowed = res.authSetting["scope.camera"];
if (!cameraAllowed) {
tt.showToast({
title: "请授权相机后重新进入"
});
}
},
});
},
onInitdone(e) {
tt.showToast({
title: "相机初始化完成",
});
},
onStop(e) {
console.log("相机中断");
},
onError(e) {
tt.showModal({
content: "相机出错了:" + e.detail.errMsg,
});
},
});
```
--------------------------------
### BackgroundAudioManager.onTimeUpdate Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/audio/background-audio-manager/background-audio-manager-on-time-update
This example demonstrates how to use `onTimeUpdate` to log the current playback position and duration. It also shows how to get the `BackgroundAudioManager` instance.
```javascript
const backgroundAudioManager = tt.getBackgroundAudioManager();
backgroundAudioManager.onTimeUpdate(() => {
console.log('currentTime: ', backgroundAudioManager.currentTime);
console.log('duration: ', backgroundAudioManager.duration);
});
```
--------------------------------
### Immediate Purchase Example (Goods Library)
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/component/industry/trading-system/pay-button-sdk
This example configures the pay-button for immediate purchase of goods from the goods library. It specifies mode 2, goods-type 1, and binds functions for getting goods info, placing an order, and payment.
```html
```
--------------------------------
### Get Performance Entries Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/foundation/performance/performance-entry
This code example demonstrates how to retrieve all performance entries using `tt.performance.getEntries()` and log their basic information to the console.
```APIDOC
## Code Example
```javascript
const entries = tt.performance.getEntries();
for (let i = 0, len = entries.length; i < len; i++) {
console.log("entry name: " + entries[i].name);
console.log("entry entryType: " + entries[i].entryType);
console.log("entry startTime: " + entries[i].startTime);
console.log("entry duration: " + entries[i].duration);
}
```
```
--------------------------------
### MediaRecorder.onStart Callback
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/canvas-recording/media-recorder/media-recorder-onstart
Sets up a listener for the start event of the MediaRecorder. The callback function is executed when recording begins. This example initializes the MediaRecorder and attaches the onStart listener.
```javascript
Page({
async onReady() {
tt.createSelectorQuery()
.select("#myCanvas")
.node()
.exec((res) => {
// 获取 canvas 实例
const canvas = res[0].node;
const canvasCtx = canvas.getContext("2d");
this.recorder = tt.createMediaRecorder(canvas, {
width: canvas.width, // video width
height: canvas.height, // video height
videoBitsPerSecond: 1000, // bit rate in kbps
gop: 12, // key frame interval
fps: 60, // frames per second
});
this.recorder.onStart(() => {
tt.showToast({
title: "start",
icon: "none",
});
});
});
},
start() {
this.recorder.start();
},
});
```
--------------------------------
### Query Order List and Details - GET Request Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/local-life/develop/OpenAPI/general-capabilities/order.query/query
This example demonstrates how to make a GET request to the Order Query API. Ensure you include the necessary headers like 'content-type' and 'access-token'. The parameters can be adjusted to filter orders by ID, status, user, or time.
```curl
curl --location --request GET 'https://open.douyin.com/goodlife/v1/trade/order/query/?ext_order_id=2EwFz6YcIK&order_id=fXFqCeprn0&cursor=[VW9olrNZjI]&update_order_end_time=1558447990847988206&get_secret_number=false&page_size=2086382090263229205&account_id=hxufVwUVIG&update_order_start_time=8573836586237235457&order_status=4612853025811756499&page_num=3803822674888668062&create_order_start_time=4757512266310011756&create_order_end_time=8062780994894207357'
--header 'content-type: application/json'
--header 'access-token: 0801121846735352506a356a6'
```
--------------------------------
### Create Pre-order with Discount
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/industry/trading-system/pre-order/create-order
This example demonstrates how to create a pre-order and apply a discount using the `discountId` parameter.
```APIDOC
## Create Pre-order with Discount
### Description
This code snippet shows how to create a pre-order with a specified discount.
### Method
`tt.createOrder`
### Parameters
- `goodsList` (Array) - Required - List of goods to be ordered.
- `quantity` (Number) - Required - Quantity of the good.
- `price` (Number) - Required - Price of the good.
- `discountAmount` (Number) - Optional - Discount amount for the good.
- `goodsName` (String) - Required - Name of the good.
- `goodsPhoto` (String) - Required - URL of the good's image.
- `goodsId` (String) - Required - ID of the good.
- `goodsType` (Number) - Required - Type of the good.
- `goodsLabels` (Array) - Optional - Labels for the good.
- `dateRule` (String) - Optional - Usage rule for the good.
- `goodsPage` (Object) - Optional - Page information for the good.
- `path` (String) - Path to the goods page.
- `params` (Object) - Parameters for the goods page.
- `payment` (Object) - Required - Payment details.
- `totalAmount` (Number) - Required - Total amount of the order.
- `totalDiscountAmount` (Number) - Optional - Total discount amount for the order.
- `contactInfo` (Object) - Optional - Contact information.
- `phoneNumber` (String) - Optional - Phone number.
- `contactName` (String) - Optional - Contact name.
- `note` (String) - Optional - Remarks for the order.
- `merchantId` (String) - Optional - Merchant ID.
- `storeInfo` (Object) - Optional - Store information.
- `storeName` (String) - Optional - Name of the store.
- `storeIcon` (String) - Optional - Icon URL of the store.
- `callbackData` (Object) - Optional - Custom data passed through.
- `tradeOption` (Object) - Optional - Trade options.
- `life_trade_flag` (Number) - Optional - Flag for integrated trade flow.
- `order_relation_info` (Object) - Optional - Information for related orders in integrated trade.
- `related_order_id` (Number) - Required if `relation_type` is present - Related order ID.
- `relation_type` (String) - Required if `related_order_id` is present - Type of relation.
- `discountId` (String) - Optional - ID for marketing information.
- `success` (Function) - Callback function on success.
- `fail` (Function) - Callback function on failure.
### Request Example
```javascript
tt.createOrder({
goodsList: [
{
quantity: 1,
price: 40000,
discountAmount: 10000,
goodsName: "测试商品",
goodsPhoto:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.ibaotu.com%2Fgif%2F19%2F48%2F47%2F76Z888piCd6W.gif%21fwpaa50%2Ffw%2F700&refer=http%3A%2F%2Fpic.ibaotu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644654365&t=5fc9b5fdad0a16264a9a9c09c14b3af9",
goodsId: "unpoi_12345",
goodsType: 2,
goodsLabels: ["随时退", "免预约"],
dateRule: "",
goodsPage: {
path:"",
params: {},
},
},
],
payment: {
totalAmount: 40000,
totalDiscountAmount: 10000,
},
contactInfo: {
phoneNumber: "12345678901",
contactName: "test name",
},
note: "for future",
merchantId: "",
storeInfo: {
storeName: "test store",
storeIcon:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.ibaotu.com%2Fgif%2F19%2F48%2F47%2F76Z888piCd6W.gif%21fwpaa50%2Ffw%2F700&refer=http%3A%2F%2Fpic.ibaotu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644654365&t=5fc9b5fdad0a16264a9a9c09c14b3af9",
},
callbackData: { test: 999999 },
tradeOption:{
life_trade_flag :0,
order_relation_info: {
related_order_id: 99999,
relation_type: "multi_buy_as_one"
}
},
discountId: "discount_test",
success: (res) => {
const { orderId, outOrderNo } = res;
console.log("success res", res);
console.log("orderId", orderId, "outOrderNo", outOrderNo);
this.setData({ orderId, outOrderNo });
},
fail: (res) => {
const { orderId, outOrderNo, errNo, errMsg, errLogId } = res;
if (errLogId) {
console.log("预下单失败", errNo, errMsg, errLogId);
}
if (orderId || outOrderNo) {
console.log("支付失败", errNo, errMsg, orderId, outOrderNo);
}
},
});
```
```
--------------------------------
### Camera Frame Listener Example
Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/media/camera/camera-frame-listener/camera-frame-listener-stop
Example demonstrating how to set up and use the CameraFrameListener, including starting and stopping frame reception. Requires camera authorization.
```html
第 {{counter}} 帧
frameWidth{{frameWidth}}; frameHeight:{{frameHeight}}
```
```javascript
let listener;
Page({
data: {
counter: 0,
frameWidth: 0,
frameHeight: 0,
},
onLoad: function (options) {
this.openCamera();
},
openCamera() {
tt.getSetting({
success: (res) => {
let cameraAllowed = res.authSetting["scope.camera"];
if (cameraAllowed) {
this.ctx = tt.createCameraContext();
} else {
tt.showToast({
title: "请授权相机后重新进入"
});
}
},
fail: (err) => {
tt.showModal({
title: "获取授权失败",
content: JSON.stringify(err),
});
},
});
}, startOnFrame(e) {
listener = this.ctx.onCameraFrame((frame) => {
let { width, height, data } = frame;
this.setData({
counter: this.data.counter + 1,
frameWidth: width,
frameHeight: height,
});
});
listener.start({
success: (res) => {
tt.showToast({ title: "开始接收帧数据" });
},
fail: (err) => {
tt.showModal({
title: "接收失败",
content: JSON.stringify(err),
});
},
});
},
stopOnFrame() {
listener.stop({
success: (res) => {
tt.showToast({ title: "停止接收帧数据" });
},
fail: (err) => {
tt.showModal({
title: "停止接收出错",
content: JSON.stringify(err),
});
},
});
},
onError(err) {
tt.showModal({
title: "相机出错了",
content: JSON.stringify(err),
});
},
});
```
--------------------------------
### Go SDK Example: Query Coupon Meta
Source: https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/sdk-overview
Example of using the Go SDK to query coupon meta information. Handles token retrieval and potential errors during SDK initialization and calls.
```go
import (
"fmt"
"testing"
credential "github.com/bytedance/douyin-openapi-credential-go/client"
openApiSdkClient "github.com/bytedance/douyin-openapi-sdk-go/client"
)
func TestCouponQueryCouponMeta(t *testing.T) {
// 初始化SDK client
opt := new(credential.Config).
SetClientKey("test_app_id").
SetClientSecret("test_app_secret")
sdkClient, err := openApiSdkClient.NewClient(opt)
if err != nil {
t.Fatal(fmt.Sprintln("sdk init err:", err))
}
// 构建请求参数
couponMetaId := "7373678331264630820"
bizType := 1
sdkRequest := &openApiSdkClient.CouponQueryCouponMetaRequest{
CouponMetaId: &couponMetaId,
BizType: &bizType,
}
// token获取与注入
// credential包提供了默认的token获取方法,但是该实现方式是基于单实例的,如果用户多实例场景使用会出现token互刷的问题。
// 开发者如果有多实例部署的需求可以自行实现token获取的逻辑
credentialHandler, err := credential.NewCredential(opt)
if err != nil {
t.Fatal(fmt.Sprintln("credential init err:", err))
}
token, err := credentialHandler.GetClientToken()
if err != nil {
t.Fatal(fmt.Sprintln("token get err:", err))
}
sdkRequest.AccessToken = token.AccessToken
// sdk调用
sdkResponse, err := sdkClient.CouponQueryCouponMeta(sdkRequest)
if err != nil {
t.Fatal(fmt.Sprintln("sdk call err:", err))
}
t.Log(sdkResponse)
}
```