字节(抖音)小游戏录屏分享,录屏播放功能

本文详细介绍了在cocoscreator2.4.x中实现字节小游戏的录屏和播放功能。通过`byteDanceManager`类,实现了游戏的录屏、暂停、恢复、停止及分享功能,并提供了录屏资源的获取。此外,还展示了如何使用离屏video进行录屏资源的播放。注意,这些功能需在真机上进行调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实现字节小游戏的录屏分享以及录屏播放功能(cocoscreator 2.4.x)

官方文档: 字节小游戏文档
项目地址: git地址

  • 效果演示请添加图片描述
演示中主要分2个功能。其一是游戏录屏,二是录屏播放。
游戏录屏
  • 代码内容

export class byteDanceManager {

    private static _instance = null;
    static instance(): byteDanceManager {
        if(!byteDanceManager._instance) {
            byteDanceManager._instance = new byteDanceManager();
        }
        return byteDanceManager._instance;
    }

    tt: any = null;

    videoHasStop: boolean = false;
    videoHasEnd: boolean = false;

    private gameRecorder: any = null;//屏幕录制管理器
    private totalRecord: number = 300;//总共录屏时间
    private recordTime: number = 0;//已经录屏时间
    private recordTimer: any = null;//录屏定时器
    private videoPath: string = '';
    private recentAdTime: Date = new Date();//上次观看广告时间,用于处理CD


    init() {
        this.tt = window["tt"];
    }

    shareGame() {

    }

    shareAppFunc(title: string, image: string, onSuccess: Function, onFail: Function){
        this.tt.shareAppMessage({
            title: title,
            imageUrl: image,
            success: () => {
                onSuccess && onSuccess();
            },
            fail: (e) => {
                onFail && onFail();
            }
        })
    }

    shareRecordVideo(title: string, videoPath: string, onSuccess: Function, onFail: Function) {
        this.tt.shareAppMessage({
            title: title,
            channel: "video",
            extra: {
                videoTopics: [],
                hashtag_list: [],
                videoPath: videoPath,
                withVideoId: true,
            },
            success: (res) => {
                onSuccess && onSuccess();
            },
            fail: (e) => {
                if(this.checkAppName()){
                    onSuccess && onSuccess();
                }else{
                    onFail && onFail();
                }
            }
        })
    }

    private checkAppName(){
        //当前今日头条ios无法获得分享成功回调
        let result = false;
        this.tt.getSystemInfo({
            success: (res) => {
                if(res.platform === 'ios' && res.appName === 'Toutiao'){
                    result = true
                }
            },
            fail: (e) => {
                console.log("getSystemInfo fail: ", e);
            }
        })
        return result;
    }

	//录屏
    startRecord(callback: Function){
        if(!this.tt) {
            callback && callback();
            return;
        }
        if(!this.gameRecorder){
            this.gameRecorder = this.tt.getGameRecorderManager();
        }
        this.videoHasEnd = false;
        this.videoHasStop = false;
        this.gameRecorder.start({duration: this.totalRecord});
        this.gameRecorder.onStart(() => {
            this.recordTime = 0;
            this.recordTimer = setInterval(() => {
                this.recordTime++;
            }, 1000);
            callback && callback();
        });

        this.gameRecorder.onResume(() => {
            this.recordTimer = setInterval(() => {
                this.recordTime++;
            }, 1000)
        });

        this.gameRecorder.onPause(() => {
            clearInterval(this.recordTimer);
        });

        this.gameRecorder.onStop((res) => {
            this.videoHasEnd = true;
            this.videoPath = res.videoPath;
            console.log("this.videoPath:", this.videoPath);
            clearInterval(this.recordTimer);
            this.recordTime = 0;
        });

        this.gameRecorder.onError((e) => {
            console.log("gameRecord error: ", e);
        })
    }

    resumeRecord(callback: Function){
        if(!this.tt) {
            return;
        }
        if(!this.gameRecorder){
            console.log("gameRecorder is null, resumeRecord fail");
        }else{
            this.gameRecorder.resume();
            callback && callback();
        }
    }

    pauseRecord(callback: Function){
        if(!this.tt) {
            return;
        }
        if(!this.gameRecorder){
            console.log("gameRecorder is null, pauseRecord fail");
        }else{
            this.gameRecorder.pause();
            callback && callback();
        }
    }

    stopRecord(callback: Function){
        if(!this.tt) {
            return;
        }
        if(!this.gameRecorder){
            console.log("gameRecorder is null, stopRecord fail")
        }else{
            this.gameRecorder.stop();
            callback && callback();
        }
    }

    getVideoPath(){
        return this.videoPath;
    }


    public onShareFunc(text: string, image: string, callback: Function){
        let channel = "";
        this.tt.getSystemInfo({
            success: (res) => {
                console.log("getSystemInfo success: ", res);
                if (res.appName === 'Douyin') {
                    channel = "invite";
                } else if(res.appName === 'Toutiao'){
                    channel = 'article';
                } else {
                    channel = '';
                }
            },
            fail: (res) => {
                console.log("getSystemInfo fail: ", res);
                channel = '';
            }
        })
        this.tt.shareAppMessage({
            // templateId: "",
            title: text,
            channel: channel,
            imageUrl: image,
            success: ()=>{
                callback && callback();
            },
            fail: ()=>{
                callback && callback();
            },
            complete: ()=>{
            }
        })
    }
}

export const btMgr = byteDanceManager.instance();

	btMgr.startRecord(()=>{})//开始录屏方法
	btMgr.stopRecord(()=>{})//停止录屏方法
录屏播放
  • 录屏播放需要在录屏停止后,从录屏停止监听中获得录屏资源地址,使用字节的离屏video渲染出来。
  • 代码内容
	let videoPath = btMgr.getVideoPath();//获取录屏文件
//播放录屏
const {ccclass, property} = cc._decorator;

@ccclass
export default class ShareVideo extends cc.Component {

    
    @property(cc.Node)
    private parentNode: cc.Node = null;
    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    private cameraNode;
    private video;
    private videoTexture: cc.Texture2D;

    start () {

    }

    initVideo(video: string){
        this.showcamera(video);
    }

    private showcamera(video: string) {
        this.cameraNode = new cc.Node();
        this.cameraNode.width = this.parentNode.width;
        this.cameraNode.height = this.parentNode.height;
        this.cameraNode.addComponent(cc.Sprite)
        this.parentNode.addChild(this.cameraNode);
        if (typeof window['tt'] !== 'undefined') {
            this.playVideo(video);
        }
    }

    private playVideo(video: string) {
        this.video = window['tt'].createOffscreenVideo();
            // 传入视频src
            this.video.src = video;
            this.video.onCanplay(() => {
                if(this.node && this.node.isValid){
                    this.video.play();
                    this.videoTexture = new cc.Texture2D();
                    this.videoTexture.initWithElement(this.video);
                    this.videoTexture.handleLoadedTexture();
                    this.cameraNode.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(this.videoTexture);
                    this.cameraNode.width = this.parentNode.width;
                    this.cameraNode.height = this.parentNode.height;

                    // this.cameraNode.width = cc.view.getVisibleSize().width;
                    // this.cameraNode.height = this.video.videoHeight / this.video.videoWidth * this.cameraNode.width;
                }
            });
            this.video.onCandraw(()=>{

            })
            this.video.onPlay(()=>{
                console.log("开始录屏");

            });
            this.video.onEnded(()=>{
            });
            this.video.onPause(()=>{
            });
        }

    update(dt) {
        if (this.video && this.videoTexture) {
            this.videoTexture.update({
                image: this.video,
                flipY: false
            });
        }
    }
}
到这里基本就完成了录屏和录屏播放的功能了。已经可以打包到字节平台调试,如果要录屏分享可以自接调用btMgr.shareRecordVideo()方法并传入相关参数即可。注意录屏以及播放功能,只能使用真机调试。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蟹 !

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值