### FileSystemManager Usage Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/file/tt-get-file-system-manager This example demonstrates how to get the FileSystemManager and read a file from the package directory. ```APIDOC ## FileSystemManager Usage Example ### Description This example shows how to obtain the FileSystemManager and then use it to read a file named 'app.js' from the package directory. ### Code ```javascript const fileSystemManager = tt.getFileSystemManager(); fileSystemManager.readFile({ filePath: "app.js", encoding: "utf8", success(res) { // Content of app.js file console.log(res.data); }, fail(res) { // Error handling console.error("Failed to read file", res.errMsg); }, }); ``` ``` -------------------------------- ### Camera.resume() Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/camera/camera-resume This example demonstrates how to create a camera instance, start the preview, pause it after 3 seconds, and then resume it after 6 seconds. It also includes a draw function to display the video feed on a canvas. ```javascript console.log("开发字节跳动小游戏过程中可以参考以下文档:"); console.log("https://developer.toutiao.com/docs/game/"); const canvas = tt.createCanvas(); const ctx = canvas.getContext("2d"); const camera = tt.createCamera(); console.log("camera", camera); camera.setBeautifyParam(0.8, 0.79, 0.4, 0.58); camera .start("front", true, { matting: true }) .then((video) => { draw(video); }) .catch((err) => { tt.showToast({ title: "相机需要授权", }); console.log(err); }); // 3s 后暂停摄像头视频画面 setTimeout(() => { camera.pause(); }, 3000); // 6s 后恢复摄像头画面 setTimeout(() => { camera.resume(); }, 6000); function draw(video) { let scale = video.videoHeight / video.videoWidth; video && ctx.drawImage( video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.width * scale, ); requestAnimationFrame(function () { draw(video); }); } ``` -------------------------------- ### Example Usage of tt.createCamera Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/media/camera/tt-create-camera This example demonstrates how to initialize a camera, set beautify parameters, start the camera, and integrate it with face detection. ```APIDOC ```javascript class Game { constructor() { this.init(); this.setCanvasWH(); this.startCamera(); this.run(); } init() { this.canvas = tt.createCanvas(); this.ctx = this.canvas.getContext("2d"); this.camera = tt.createCamera(); this.detector = tt.createFaceDetector(); console.log(this.detector); this.handleDetectionResult(); tt.setKeepScreenOn(); this.frame = 0; } setCanvasWH() { let info = tt.getSystemInfoSync(); this.canvas.width = info.windowWidth; this.canvas.height = info.windowHeight; } startCamera() { this.camera.setBeautifyParam(1, 1, 1, 1); this.camera .start("front", true) .then((video) => { console.log(`succeed to open camera`); this.mediaStream = video; }) .catch((err) => { console.log(err); }); } startDetector() { this.mediaStream && this.detector .detectFaces(this.mediaStream) .then((res) => { console.log(res); // 对应最下方的人脸信息(检测数据)内容说明 }) .catch((err) => { console.log(err); }); } handleDetectionResult() { let actions = { blink: "眨眼", blink_left: "左眨眼", blink_right: "右眨眼", mouth_ah: "嘴巴大张", head_yaw: "摇头", head_yaw_indian: "印度式摇头", head_pitch: "点头", brow_jump: "眉毛挑动", mouth_pout: "嘟嘴", }; this.detector.onActions((detectData) => { for (let act of detectData.actions) { console.log(`检测到 ${actions[act]} 动作`); } }); this.detector.onBlink((detectData) => { console.log("检测到眨眼动作"); console.log(detectData); }); } paintVideoToCanvas() { let video = this.mediaStream; let canvas = this.canvas; if (video) { let scale = video.videoHeight / video.videoWidth; video && this.ctx.drawImage( video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.width * scale ); } } run() { if (this.frame >= 5) { this.frame = 0; this.startDetector(); // detect faces once every five frames } else { this.frame++; } this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.paintVideoToCanvas(); requestAnimationFrame(() => { this.run(); }); } } new Game(); ``` ``` -------------------------------- ### 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 Use tt.getLaunchOptionsSync to get launch scene and query parameters. This helps identify the recommendation feed direct play scenario and allows for special handling of user activity tracking. ```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| 获客用户| ​ ``` -------------------------------- ### Create FastForwardNode and Start Writing Audio Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/media/audio/AudioContext/audio-context-create-fast-forward This example demonstrates how to create an AudioContext, an audio source, and a FastForwardNode. It then downloads an audio file, sets it as the audio source, connects the source to the FastForwardNode, and starts the fast-forward writing process to a specified file path with a given sample count. It also includes error handling for the file download. ```javascript const ctx = tt.getAudioContext(); const audio = ctx.createAudio(); const source = context.createMediaElementSource(audio); const ffwdNode = ctx.createFastForward(); //创建FastForwardNode tt.downloadFile({ url: "https://xxxx.mp3", // 合法的音频文件路径 success(res) { audio.src = res.tempFilePath; //预下载临时路径 audio.loop = true; audio.startTime = 0; audio.autoplay = true; source.connect(ffwdNode); //连接到快速输出节点 ffwdNode.onended = () => { //快速录制完成回调,此时输出文件可用 }; ffwdNode.start( `${tt.env.USER_DATA_PATH}/FFWDFile.wav`, ctx.sampleRate * 10 ); //需要指定输出路径和样本数 }, fail(err) { tt.showModal({ title: "下载失败", content: `失败原因: ${err.errMsg}`, }); }, }); ``` -------------------------------- ### Example Usage Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-on-frame-recorded This example demonstrates how to use `RecorderManager.onFrameRecorded` to log the size of recorded audio frames. It also shows the necessary setup for `RecorderManager.start` including the `frameSize` parameter. ```APIDOC ## Code Example ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.onFrameRecorded((res) => { console.log("录音帧数据大小 " + res.frameBuffer.byteLength); }); recorderManager.start({ duration: 60000, sampleRate: 12000, numberOfChannels: 1, encodeBitRate: 25000, frameSize: 100, }); ``` ``` -------------------------------- ### Get Launch Options Sync C# Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/c-api/system/game-launch-params Call TT.GetLaunchOptionsSync after TT.InitSDK to ensure non-null values. This example demonstrates how to retrieve and log various launch parameters including path, scene, query, refererInfo, and extra data. Remember to check for null values as parameters may be empty. ```csharp void Read_LaunchOption() { Debug.Log("LaunchOption: "); if (TT.s_ContainerEnv != null) { TTSDK.LaunchOption launchOption = TT.GetLaunchOptionsSync(); Debug.Log("path :" + launchOption.Path); Debug.Log("scene :" + launchOption.Scene); Debug.Log("subScene :" + launchOption.SubScene); Debug.Log("group_id :" + launchOption.GroupId); Debug.Log("shareTicket :" + launchOption.ShareTicket); Debug.Log("is_sticky :" + launchOption.IsSticky); Debug.Log("query : "); if (launchOption.Query != null) { foreach (KeyValuePair kv in launchOption.Query) if (kv.Value != null) Debug.Log(kv.Key + ": " + kv.Value); else Debug.Log(kv.Key + ": " + "null "); } Debug.Log("refererInfo : "); if (launchOption.RefererInfo != null) { foreach (KeyValuePair kv in launchOption.RefererInfo) if (kv.Value != null) Debug.Log(kv.Key + ": " + kv.Value); else Debug.Log(kv.Key + ": " + "null "); } Debug.Log("extra : "); if (launchOption.Extra != null) { foreach (KeyValuePair kv in launchOption.Extra) if (kv.Value != null) Debug.Log(kv.Key + ": " + kv.Value); else Debug.Log(kv.Key + ": " + "null "); } } } ``` -------------------------------- ### Example: Start recording without input parameters Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-start Starts recording with default parameters. The `onFrameRecorded` callback will not be triggered. ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.start(); // All parameters are default values tt.showToast({ title: "Clicked start recording, parameters are default values" }); ``` -------------------------------- ### Get File Info Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/file/file-system-manager/file-system-manager-get-file-info This example demonstrates how to use FileSystemManager.getFileInfo to get information about a chosen image file. It first uses tt.chooseImage to select a file and then passes its path to the getFileInfo function, which calls the FileSystemManager.getFileInfo API. ```javascript const fileSystemManager = tt.getFileSystemManager(); tt.chooseImage({ success(res) { getFileInfo(res.tempFilePaths[0]); }, }); function getFileInfo(filePath) { fileSystemManager.getFileInfo({ filePath, success(res) { console.log("文件信息:", res); }, fail(res) { console.log("调用失败", res.errMsg); }, }); } ``` -------------------------------- ### Start Accelerometer Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/device/jerkmeter/tt-start-accelerometer This example demonstrates how to call the tt.startAccelerometer API and handle success and failure callbacks. ```APIDOC ## tt.startAccelerometer ### Description Starts listening for accelerometer data. The actual accelerometer data is obtained by registering the callback method of tt.onAccelerometerChange. ### Method `tt.startAccelerometer(options)` ### Parameters #### Options Object - `success` (function) - Optional - Callback function when the API call is successful. - `fail` (function) - Optional - Callback function when the API call fails. - `complete` (function) - Optional - Callback function that executes after the API call completes (whether successful or failed). ### Request Example ```javascript tt.startAccelerometer({ success(res) { console.log("调用成功", res.errMsg); }, fail(res) { console.log("调用失败", res.errMsg); } }); ``` ### Response #### Success Response An object with the following property: - `errMsg` (string) - Indicates the success of the operation, e.g., "startAccelerometer:ok". #### Failure Response An object with the following property: - `errMsg` (string) - Indicates the failure of the operation, e.g., "startAccelerometer:fail" + detailed error message. ### Error Codes - `21100`: sensor disable - `21000`: The current device does not support accelerometers or the accelerometer is already running. - `20001`: invalid param - `20000`: internal error ``` -------------------------------- ### Example: Start recording without setting frameSize Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-start Starts recording with specified parameters, but without the `frameSize`. The `onFrameRecorded` callback will not be triggered. ```javascript const recorderManager = tt.getRecorderManager(); const options = { duration: 1000, sampleRate: 12000, numberOfChannels: 1, encodeBitRate: 25000, frameSize: 100, }; recorderManager.start(options); tt.showToast({ title: "Clicked start recording" }); ``` -------------------------------- ### 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 Retrieves the watermark dimensions using `recorder.getMark()` and then uses these dimensions to center the watermark when starting the screen recording. This example also includes setting up an `onStart` listener. ```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, }); }, }); ``` -------------------------------- ### Query, Update, and Remove with Multiple Conditions Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/game-engine/rd-to-SCgame/unity-game-access/dycloud-csharp-interface Example demonstrating how to construct complex queries with multiple conditions (skip, limit, order, field) before executing Get, Count, Update, or Remove operations. This snippet shows the setup for these operations. ```csharp Dictionary query = new Dictionary(); query[queryKey] = exceptValue; CloudDBCollection cloudDBCollection = StarkSDK.API.GetStarkDouyinCloudManager().CloudDb() .GenDBCollection(DY_CLOUD_EVN_ID, DY_CLOYD_DB_NAME); if (skip > 0) { cloudDBCollection.Skip(skip); } cloudDBCollection.Where(query); if (limit > 0) { cloudDBCollection.Limit(limit); } if (isCheckOrder) { cloudDBCollection.OrderBy(orderKey, orderDirection); } if (field != null) { cloudDBCollection.Field(field); } // 上述条件设置完成后, 调用具体的查询 、更新方法 cloudDBCollection.Get( response => { // TODO check add PrintText( $"TestDBAdd RawCloudDb response.StatusCode:{response.StatusCode},response.Data:{response.Data.ToJson()}"); }, response => { PrintText( $"TestDBAdd RawCloudDb response.StatusCode:{response.StatusCode},response.ErrMsg:{response.ErrMsg}"); }) ``` -------------------------------- ### Log Launch Options Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/system/lifecycle/tt-get-launch-options-sync This example demonstrates how to retrieve and log the launch options using tt.getLaunchOptionsSync(). ```javascript var options = tt.getLaunchOptionsSync(); console.log(options); ``` -------------------------------- ### Listen for Recording Resume Event Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-on-resume Get the RecorderManager instance and set up a listener for the resume event. The callback function logs a message to the console. The example also includes starting, pausing, and resuming the recording, and triggering resume on touch end. ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.onResume(() => { console.log("继续录音"); }); recorderManager.start(); setTimeout(() => { recorderManager.pause(); console.log("暂停录音"); }, 2000); tt.onTouchEnd(() => { recorderManager.resume(); }); ``` -------------------------------- ### Banner Ad Creation and Display Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/c-api/ads/banner-ads Example demonstrating how to create a banner ad instance and show it upon successful loading. Includes callback functions for error handling, loading, resizing, and closing. ```csharp public void TestCreatAd() { m_bannerAdIns = TT.CreateBannerAd(Common.GetBannerAdId(), m_style, 60, OnAdError, OnBannerLoaded, OnBannerResize, OnClose); } void OnAdError(int iErrCode, string errMsg) { Debug.LogError(TAG + "错误 : " + iErrCode + " " + errMsg); } private void OnBannerLoaded() { m_bannerAdIns?.Show(); m_result.text = m_result.text + "/n" + "banner广告loaded"; } private void OnBannerResize(int width, int height) { Debug.Log($"OnBannerResize - width:{width} height:{height}"); } private void OnClose() { Debug.Log("banner广告关闭"); } ``` -------------------------------- ### tt.request with GET Method Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/network/initiate-a-request/tt-request Example of making a GET request using tt.request. The 'data' parameter is optional for GET requests. ```javascript tt.request({ url: "your_api_url", method: "GET", success: function(res) { console.log(res.data); }, fail: function(err) { console.log(err); } }); ``` -------------------------------- ### Remove Gyroscope Change Listener Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/device/gyroscope/tt-off-gyroscope-change This example demonstrates how to remove a gyroscope change listener after it has been set up. It first starts the gyroscope to get data at a specified interval, then sets up a handler for gyroscope changes, and finally uses `setTimeout` to call `tt.offGyroscopeChange` after one second to stop listening. ```javascript tt.startGyroscope({ interval: 100 }); function handler(param) { console.log("陀螺仪数据:x ", param.x); console.log("陀螺仪数据:y ", param.y); console.log("陀螺仪数据:z ", param.z); console.log("陀螺仪数据:t ", param.t); console.log("陀螺仪数据:result ", param.result); } tt.onGyroscopeChange(handler); setTimeout(() => { // 一秒之后卸载监听函数 tt.offGyroscopeChange(); }, 1000); ``` -------------------------------- ### Go: Query Coupon Meta Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/server/sdk-overview This Go snippet demonstrates how to query coupon meta information. It includes initialization of the SDK client, building request parameters, and obtaining an access token. Note that the default token retrieval might not be suitable for multi-instance deployments. ```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) } ``` -------------------------------- ### Command-line Upload Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/dev-tools/development-assistance/ide-cli An example of how to use the `tmg upload` command with specific parameters. This includes setting the project path, app version, changelog, output path for the QR code, test channel, and background color for the QR code. ```bash tmg upload /YOUR/PROJECT/PATH \ -v 0.0.1 \ -c "update change log" \ -o /OUTPUR/QRCODE \ --channel 1 \ -b "#ffffffff" ``` -------------------------------- ### Java Example for Signature Verification Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/payment/payment-server-callback Example implementation in Java for verifying the signature of an incoming GET request for interface accessibility. ```java import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.security.MessageDigest; import javax.xml.bind.DatatypeConverter; public class SignatureVerifier { public String verify(String token, String timestamp, String nonce, String msg, String signature, String echostr) { List sortedString = new ArrayList<>(); sortedString.add(token); sortedString.add(timestamp); sortedString.add(nonce); sortedString.add(msg); Collections.sort(sortedString); String joinStr = String.join("", sortedString); try { MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] b = md.digest(joinStr.getBytes()); String calculatedSignature = DatatypeConverter.printHexBinary(b).toLowerCase(); if (calculatedSignature.equals(signature)) { return echostr; } } catch (Exception e) { e.printStackTrace(); } return null; } } ``` -------------------------------- ### Copy File Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/file/file-system-manager/file-system-manager-copy-file-sync This example demonstrates downloading a network resource and then synchronously copying it to a user-defined path. The destination path must begin with `ttfile://user`. ```javascript const fileSystemManager = tt.getFileSystemManager(); // 下载网络资源 tt.downloadFile({ url: "https://s3.pstatp.com/toutiao/resource/developer/static/img/main-logo.8e3a839.png", success(res) { console.log("下载成功", res.tempFilePath); try { // 拷贝文件, destPath 目录必须以 `ttfile://user` 开头 fileSystemManager.copyFileSync( res.tempFilePath, `ttfile://user/logo.png` ); console.log("拷贝成功"); } catch (err) { console.log("拷贝失败", err); } }, fail(res) { console.log("下载失败", res.errMsg); }, }); ``` -------------------------------- ### Read File Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/file/tt-get-file-system-manager Example demonstrating how to read a file from the package directory using the FileSystemManager. Note that accessing the package directory does not require a prefix. ```APIDOC ## FileSystemManager.readFile ### Description Reads the content of a file. ### Method Asynchronous ### Endpoint N/A (Client-side API) ### Parameters #### Request Body - **filePath** (string) - Required - The path to the file to read. For package directory files, use the relative path (e.g., "app.js"). - **encoding** (string) - Optional - The encoding of the file. Defaults to 'utf8'. - **success** (function) - Callback function for successful read. - **res** (object) - **data** (string) - The content of the file. - **fail** (function) - Callback function for failed read. - **res** (object) - **errMsg** (string) - Error message. ### Request Example ```javascript const fileSystemManager = tt.getFileSystemManager(); fileSystemManager.readFile({ filePath: "app.js", encoding: "utf8", success(res) { console.log(res.data); }, fail(res) { console.error("读取失败", res.errMsg); }, }); ``` ### Response #### Success Response (200) - **data** (string) - The content of the file. #### Response Example ```json { "data": "// Content of app.js" } ``` ``` -------------------------------- ### Golang Example for Signature Verification Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/payment/payment-server-callback Example implementation in Golang for verifying the signature of an incoming GET request for interface accessibility. ```golang package main import ( "crypto/sha1" "fmt" "sort" "strings" ) func verifySignature(token, timestamp, nonce, msg, signature, echostr string) string { sortedString := []string{token, timestamp, nonce, msg} sort.Strings(sortedString) h := sha1.New() h.Write([]byte(strings.Join(sortedString, ""))) calculatedSignature := fmt.Sprintf("%x", h.Sum(nil)) if calculatedSignature == signature { return echostr } return "" } ``` -------------------------------- ### Create and Use FastForwardNode Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/audio/AudioContext/audio-context-create-fast-forward This example demonstrates how to create an AudioContext, an Audio object, and a FastForwardNode. It then downloads an audio file, sets it as the audio source, connects the source to the FastForwardNode, and starts the fast-forward writing process to a specified file path. The `onended` callback is used to handle the completion of the recording. ```javascript // 创建一个 AudioContext 和 Audio const ctx = tt.getAudioContext(); const audio = ctx.createAudio(); const source = context.createMediaElementSource(audio); const ffwdNode = ctx.createFastForward(); //创建FastForwardNode tt.downloadFile({ url: "https://xxxx.mp3", // 合法的音频文件路径 success(res) { audio.src = res.tempFilePath; //预下载临时路径 audio.loop = true; audio.startTime = 0; audio.autoplay = true; source.connect(ffwdNode); //连接到快速输出节点 ffwdNode.onended = () => { //快速录制完成回调,此时输出文件可用 }; ffwdNode.start( `${tt.env.USER_DATA_PATH}/FFWDFile.wav`, ctx.sampleRate * 10 ); //需要指定输出路径和样本数 }, fail(err) { tt.showModal({ title: "下载失败", content: `失败原因: ${err.errMsg}`, }); }, }); ``` -------------------------------- ### Stop Recording Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-stop This example demonstrates how to stop an audio recording after it has been started. It uses a setTimeout to stop the recording after 2 seconds. ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.start(); console.log("录音开始"); setTimeout(() => { recorderManager.stop(); console.log("录音结束"); }, 2000); ``` -------------------------------- ### File System Manager Stats Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/file/stats/stats Example demonstrating how to get file stats using `tt.getFileSystemManager()` and access its properties and methods. ```APIDOC ## File System Manager Stats Example ### Description This example shows how to retrieve file statistics and use the `isDirectory` and `isFile` methods. ### Code Example ```javascript const fs = getFileSystemManager(); const stat = fs.statSync("./path"); console.log("mode:", stat.mode); console.log("size:", stat.size); console.log("lastAccessedTime:", stat.lastAccessedTime); console.log("lastModifiedTime:", stat.lastModifiedTime); console.log("isDirectory:", stat.isDirectory()); console.log("isFile:", stat.isFile()); ``` ``` -------------------------------- ### Preview Mini Game Project CLI Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/developer-instrument/development-assistance/ide-cli Command-line interface for previewing a mini-game project. Specify the project path. Optionally, provide an output path to save the QR code image. ```bash tmg preview /YOUR/PROJECT/PATH # 这里的path是项目工程的根目录。该目录下应该有一个project.config.json的文件 tmg preview /YOUR/PROJECT/PATH -o /PREVIEW/QRCODE/PATH ``` -------------------------------- ### Listen for Recording Start Event Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-on-start Use this snippet to listen for the recording start event and display a toast message. It also includes an example of how to trigger the start of recording on a touch end event. ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.onStart(() => { tt.showToast({ title: "录音开始" }); }); tt.onTouchEnd(() => { recorderManager.start(); }); ``` -------------------------------- ### Start Recording with Default Parameters Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-start Initiates recording with all parameters set to their default values. Use this when no specific configuration is needed. ```javascript const recorderManager = tt.getRecorderManager(); recorderManager.start(); // 所有参数为默认值 tt.showToast({ title: "点击了开始录音,参数为默认值" }); ``` -------------------------------- ### Node.js (Koa) Example for Signature Verification Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/payment/payment-server-callback Example implementation in Node.js using Koa for verifying the signature of an incoming GET request for interface accessibility. ```javascript const crypto = require('crypto'); async function handler(ctx) { const { signature, timestamp, nonce, echostr } = ctx.query; const token = 'YOUR_SERVER_CALLBACK_TOKEN'; // Replace with your actual token const msg = ''; // Typically empty for verification const strArr = [token, timestamp, nonce, msg].sort(); const str = strArr.join(''); const _signature = crypto.createHash('sha1').update(str).digest('hex'); if (_signature === signature) { ctx.body = echostr; } else { ctx.body = ''; } } ``` -------------------------------- ### Download Sample Code for StarkSDK Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/game-engine/rd-to-SCgame/unity-game-access/install-connect/sc_faq Access the provided URL to download a sample project demonstrating the usage of the StarkSDK. This is helpful for understanding how to implement various SDK features. ```url https://sf3-g-cn.dailygn.com/obj/sf-game-lf/testgn/StarkSDK-Sample.zip ``` -------------------------------- ### Get Video Record State Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/c-api/media/record Retrieves the current state of the video recording. Use this to check if recording is starting, started, paused, stopped, completed, or if an error occurred. ```csharp public abstract TTGameRecorder.VideoRecordState GetVideoRecordState(); ``` -------------------------------- ### Code Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/c-api/basics/tt-can-i-use Example demonstrating how to use CanIUse to check the availability of GetUserInfoAuth and GetSystemInfo. ```APIDOC ## Code Example ### Description This example shows how to use the `CanIUse` interface to check the availability of specific features like `GetUserInfoAuth` and `GetSystemInfo`. ### Code ```csharp void Test() { Debug.Log($"GetUserInfoAuth: {CanIUse.GetUserInfoAuth}"); Debug.Log($"GetSystemInfo: {CanIUse.GetSystemInfo}"); } ``` ``` -------------------------------- ### Example Request Parameters for Get Balance Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/payment/acquire-mini-game-coin-balance Provides an example of the JSON payload required to call the get_balance API. Ensure parameters like openid and zone_id match those used during recharge. ```JSON { "openid": "fge35vh5h3f2", "appid": "tthdch45hd2df", "zone_id": "1", "mp_sig": "d1f0a41272f9b85618361323e1b19cd8cb0213f2", "access_token": "hds2rt6bhgh5wfg5nf4gdh6", "ts": 1507530737, "pf": "android" } ``` -------------------------------- ### Initialize Package Splitting Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/game-engine/rd-to-SCgame/open-capacity/performance-optimization/start-up/code-upload/sc_webgl_split Use this command to start the splitting process by initializing a prepare package. This package instruments all functions for subsequent collection. Ensure you replace placeholders with your actual paths, appId, and version description. ```bash tt-wasmsplit-ci init -p -i -m ``` -------------------------------- ### Initialize File System Manager - C# Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/c-api/file/get-file-manager Demonstrates how to get the file system manager instance. This is the first step before performing any file operations. ```csharp public void TestFileSystem() { var fileSystemManager = TT.GetFileSystemManager(); } ``` -------------------------------- ### Camera.start Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/camera/camera Starts the camera. It can optionally apply beautification effects. ```APIDOC ## Camera.start ### Description Starts the camera. ### Method `Camera.start(string face, bool beautify, Object option)` ### Parameters * **face** (string) - Specifies the face detection mode. * **beautify** (bool) - Enables or disables beautification. * **option** (Object) - Optional configuration parameters. ``` -------------------------------- ### Get Screen Brightness Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/device/screen-intensity/tt-get-screen-brightness This example demonstrates how to call the tt.getScreenBrightness API and handle the success and failure callbacks. ```APIDOC ## tt.getScreenBrightness ### Description Gets the current screen brightness of the device. ### Method `tt.getScreenBrightness(options)` ### Parameters - **options** (object) - Optional - **success** (function) - Callback function when the API call is successful. - **fail** (function) - Callback function when the API call fails. - **complete** (function) - Callback function that executes when the API call is completed (whether successful or failed). ### Success Response - **value** (number) - The screen brightness value, ranging from 0 (darkest) to 1 (brightest). - **errMsg** (string) - Indicates the success of the operation, e.g., "getScreenBrightness:ok". ### Failure Response - **errMsg** (string) - Indicates the failure of the operation, e.g., "getScreenBrightness:fail" + detailed error information. ### Code Example ```javascript tt.getScreenBrightness({ success: (res) => { console.log("getScreenBrightness success", res); }, fail: (res) => { console.log("getScreenBrightness fail", res); } }); ``` ``` -------------------------------- ### Create AnalyserNode and Visualize Audio Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/audio/AudioContext/audio-context-create-analyser This example demonstrates how to create an AnalyserNode, connect it to an audio source, and visualize the audio data on a canvas. It retrieves time-domain data and draws a waveform. Ensure the audio file path is correct. ```javascript const ctx = tt.getAudioContext(); const audio = ctx.createAudio(); audio.src = "xxxx.mp3"; audio.oncanplay = () => { audio.play(); }; const source = ctx.createMediaElementSource(audio); const analyser = ctx.createAnalyser(); source.connect(analyser); var bufferLength = analyser.frequencyBinCount; var dataArray = new Uint8Array(bufferLength); analyser.getByteTimeDomainData(dataArray); // 获取画板 var canvas = tt.createCanvas(); var canvasCtx = canvas.getContext("2d"); // 把音频数据画到canvas上 function draw() { requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); canvasCtx.fillStyle = "rgb(200, 200, 200)"; canvasCtx.fillRect(0, 0, canvas.width, canvas.height); canvasCtx.lineWidth = 2; canvasCtx.strokeStyle = "rgb(0, 0, 0)"; canvasCtx.beginPath(); var sliceWidth = (canvas.width * 1.0) / bufferLength; var x = 0; for (var i = 0; i < bufferLength; i++) { var v = dataArray[i] / 128.0; var y = (v * canvas.height) / 2; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sliceWidth; } canvasCtx.lineTo(canvas.width, canvas.height / 2); canvasCtx.stroke(); } draw(); ``` -------------------------------- ### Resume Recording Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/javascript-api/media/record/recorder-manager/recorder-manager-resume This example demonstrates how to use RecorderManager.resume. It starts recording, then pauses it on a touch end event. If recording is paused, it resumes; otherwise, it pauses. Toast messages indicate the current recording state. ```javascript const recorderManager = tt.getRecorderManager(); let isRecording = false; recorderManager.start(); isRecording = true; tt.showToast({ title: "开始录音" }); tt.onTouchEnd(() => { if (isRecording) { recorderManager.pause(); tt.showToast({ title: "暂停录音" }); isRecording = false; } else { recorderManager.resume(); tt.showToast({ title: "继续录音" }); isRecording = true; } }); ``` -------------------------------- ### AudioNode Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/media/audio/AudioContext/audio-node Example demonstrating how to create an AudioContext, an oscillator, a gain node, and connect them. ```APIDOC ```javascript const audioCtx = tt.getAudioContext(); const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); ``` ``` -------------------------------- ### Response Example for Get User Group Tag API Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/server/game-group-tag/get-user-group-tag This JSON structure represents a successful response from the Get User Group Tag API, including status, error codes, and the list of user group tags. ```json { "BaseResp": { "StatusCode": 0, "StatusMessage": "" }, "err_msg": "", "err_no": 0, "log_id": "20250723113624C502D1DD796BBE1A7E9D", "user_group_tag_list": [ { "status": 1, "tag_id": "547998720770", "template_id": "546358272258" } ] } ``` -------------------------------- ### Complete RTC Engine Example Source: https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/api/media/rtc/tt-get-rtc-engine This example demonstrates the complete lifecycle of using the RTC engine, from obtaining an instance and setting up event listeners to joining a channel and enabling local audio. ```javascript // 1. 获取实例 const rtcEngine = tt.getRtcEngine("RTC AppId"); // 2. 监听需要的事件 rtcEngine.onJoinChannelSuccess( () => {}) rtcEngine.onConnectionLost( () => {}) rtcEngine.onWarning( () => {}) rtcEngine.onError( () => {}) // 3. 获取频道(对接开发者服务获取)和 token (参考火山 token 生成) let channelId = "channelIdtest"; let token = "testToken"; // 4. 广播连麦 channelId,所有用户加入频道 rtcEngine.joinChannel({ channelId, uid: 'user1', token }); // 5. 开启本地推流 rtcEngine.enableLocalAudio(); rtcEngine.leaveChannel(); rtcEngine.leaveChannel(); ```