You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
9.3 KiB
272 lines
9.3 KiB
import { sys, _decorator } from 'cc';
|
|
import { MiniGamePlatform } from '../platform/MiniGamePlatform';
|
|
|
|
const IGG_URL: string = 'https://gate.snssdk.com/developer/api/get_top_video_ids_by_like';
|
|
const NEW_URL: string = 'https://gate.snssdk.com/developer/api/get_top_video_ids_by_time';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
/**
|
|
* 头条录屏相关。
|
|
* 鸿蒙:视频挂载/录屏分享等开放能力需 canIUse,不支持则降级,禁止直接裸调 tt API。
|
|
* @see https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/open-capabilities/general-capabilities/miniapp-harmony-adapter
|
|
*/
|
|
@ccclass
|
|
export default class TTRecording {
|
|
|
|
static Ins: TTRecording = new TTRecording();
|
|
|
|
private _recorder: any;
|
|
private _videoPath: string = '';
|
|
private _iTime: number = 0;
|
|
private _timeOutId;
|
|
private _isStop: boolean = true;
|
|
|
|
private _appid = ``;
|
|
private _game_name = ``;
|
|
|
|
getVideoPath() {
|
|
return this._videoPath;
|
|
}
|
|
|
|
getVideoTime() {
|
|
return this._iTime;
|
|
}
|
|
|
|
getStatus() {
|
|
return !this._isStop;
|
|
}
|
|
|
|
init(data) {
|
|
MiniGamePlatform.init();
|
|
if (data && data.appid) this._appid = data.appid;
|
|
if (data && data.gameName) this._game_name = data.gameName;
|
|
|
|
// 鸿蒙/低版本:录屏管理器不可用则跳过,避免同步 throw 阻塞启动
|
|
if (!MiniGamePlatform.canIUse('getGameRecorderManager')) {
|
|
console.warn('[TTRecording] getGameRecorderManager unavailable (harmony/low SDK)');
|
|
return;
|
|
}
|
|
const tt = MiniGamePlatform.pf as any;
|
|
if (!tt?.getGameRecorderManager || this._recorder != null) return;
|
|
|
|
const self = this;
|
|
try {
|
|
this._recorder = tt.getGameRecorderManager();
|
|
} catch (e) {
|
|
console.warn('[TTRecording] getGameRecorderManager throw', e);
|
|
this._recorder = null;
|
|
return;
|
|
}
|
|
this._recorder.onStart((res) => {
|
|
console.log('录屏开始');
|
|
self._isStop = false;
|
|
self._videoPath = null;
|
|
self._iTime = 0;
|
|
clearInterval(self._timeOutId);
|
|
self._timeOutId = setInterval(() => {
|
|
!self._isStop && self._iTime++;
|
|
}, 1000);
|
|
});
|
|
this._recorder.onStop((res) => {
|
|
self._isStop = true;
|
|
const time = self._iTime >= 30 ? 30 : self._iTime;
|
|
if (time < 3) return;
|
|
console.log(time + 'onStop=', res, time);
|
|
self._recorder.clipVideo({
|
|
path: res.videoPath,
|
|
timeRange: [time, 0],
|
|
success(clipRes) {
|
|
console.log(time + clipRes.videoPath);
|
|
self._videoPath = clipRes.videoPath;
|
|
},
|
|
fail(e) {
|
|
console.error(e);
|
|
},
|
|
});
|
|
});
|
|
}
|
|
|
|
startVideo() {
|
|
if (this._recorder) {
|
|
this._recorder.stop();
|
|
this._recorder.start({
|
|
duration: 300,
|
|
});
|
|
this._isStop = false;
|
|
}
|
|
}
|
|
|
|
pauseVideo() {
|
|
this._recorder && this._recorder.pause();
|
|
}
|
|
|
|
resumeVideo() {
|
|
this._recorder && this._recorder.resume();
|
|
if (this._isStop) {
|
|
this.startVideo();
|
|
}
|
|
}
|
|
|
|
stopVideo() {
|
|
if (this._recorder && !this._isStop) {
|
|
this._recorder.stop();
|
|
this._isStop = true;
|
|
}
|
|
}
|
|
|
|
shareVideo(successFunc: Function) {
|
|
this._timeOutId > -1 && clearInterval(this._timeOutId);
|
|
const path = this._videoPath;
|
|
|
|
if (this._iTime < 3) {
|
|
console.log('录屏失败:录屏时长低于 3 秒');
|
|
successFunc && successFunc(false);
|
|
return;
|
|
}
|
|
if (!this._videoPath) {
|
|
successFunc && successFunc(false);
|
|
console.log('shareVideo 分享失败', path, this._iTime);
|
|
return;
|
|
}
|
|
|
|
// 官方:不支持的 API 先 canIUse;鸿蒙视频分享常不可用,降级不阻塞
|
|
if (!MiniGamePlatform.isDouyinVideoOpenCapabilityAvailable('shareAppMessage')) {
|
|
console.warn('[TTRecording] shareAppMessage unavailable on this OS');
|
|
MiniGamePlatform.pf?.showToast?.({ title: '当前系统暂不支持分享录屏', icon: 'none' });
|
|
successFunc && successFunc(false);
|
|
return;
|
|
}
|
|
|
|
console.log('shareVideo 分享开始', this._iTime);
|
|
this._videoPath = null;
|
|
const gameName = this._game_name;
|
|
MiniGamePlatform.invokeAsync('shareAppMessage', {
|
|
channel: 'video',
|
|
extra: {
|
|
videoPath: path,
|
|
videoTopics: [gameName],
|
|
withVideoId: true,
|
|
},
|
|
success() {
|
|
successFunc && successFunc(true);
|
|
console.log('分享视频成功');
|
|
},
|
|
fail(e: { errMsg?: string; errNo?: number }) {
|
|
successFunc && successFunc(false);
|
|
console.log('分享视频失败', e?.errMsg, e?.errNo);
|
|
if (e?.errNo === 10302) {
|
|
MiniGamePlatform.pf?.showToast?.({ title: '当前系统暂不支持分享录屏', icon: 'none' });
|
|
return;
|
|
}
|
|
if (e?.errMsg && e.errMsg.indexOf('short') != -1) {
|
|
console.log('分享视频失败,视频时间过短');
|
|
MiniGamePlatform.pf?.showToast?.({ title: 'video time too short', icon: 'fail' });
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
getVideoDiggRank(token: string, cb: Function) {
|
|
this.requestVideoRank(token, IGG_URL, cb);
|
|
}
|
|
|
|
getVideoNewRank(token: string, cb: Function) {
|
|
this.requestVideoRank(token, NEW_URL, cb);
|
|
}
|
|
|
|
requestVideoRank(token: string = '', url: string = '', cb: Function) {
|
|
if (!MiniGamePlatform.canIUse('request')) {
|
|
cb && cb(null);
|
|
return;
|
|
}
|
|
MiniGamePlatform.invokeAsync('request', {
|
|
url: url,
|
|
method: 'POST',
|
|
data: {
|
|
app_id: this._appid,
|
|
number_of_top: 100,
|
|
access_token: token,
|
|
},
|
|
success: (res: { data?: { err_no?: number; data?: unknown } }) => {
|
|
if (res?.data?.err_no !== 0) {
|
|
cb && cb(null);
|
|
console.log('视频排行数据获取失败=====');
|
|
} else {
|
|
console.log(res);
|
|
cb && cb(res.data.data);
|
|
}
|
|
},
|
|
fail: () => {
|
|
cb && cb(null);
|
|
},
|
|
});
|
|
}
|
|
|
|
/** 排行视频点击跳转(鸿蒙/低版本不支持则 toast 降级) */
|
|
navigateToVideo(videoId: number) {
|
|
if (!MiniGamePlatform.isDouyinVideoOpenCapabilityAvailable('navigateToVideoView')) {
|
|
console.warn('[TTRecording] navigateToVideoView unavailable on this OS');
|
|
MiniGamePlatform.pf?.showToast?.({ title: '当前系统暂不支持打开视频', icon: 'none' });
|
|
return;
|
|
}
|
|
MiniGamePlatform.invokeAsync('navigateToVideoView', {
|
|
videoId: videoId,
|
|
success: () => {
|
|
console.log('navigateToVideoView done');
|
|
},
|
|
fail: (err: { errCode?: number; errNo?: number }) => {
|
|
if (err?.errNo === 10302 || err?.errCode === 1006) {
|
|
MiniGamePlatform.pf?.showToast?.({
|
|
title: err?.errNo === 10302
|
|
? '当前系统暂不支持打开视频'
|
|
: 'something wrong with your network',
|
|
});
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
request(url: string = '', data: any = null, method: string = '', success: Function = null, fail: Function = null, complete: Function = null) {
|
|
if (sys.platform == sys.Platform.DESKTOP_BROWSER) return;
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState == 4) {
|
|
const response = xhr.responseText;
|
|
if (xhr.status >= 200 && xhr.status < 400) {
|
|
let result = {};
|
|
try {
|
|
result = JSON.parse(response);
|
|
} catch (e) {
|
|
console.error('json parse error ', response);
|
|
fail && fail(e);
|
|
}
|
|
success && success(result);
|
|
} else {
|
|
console.error('error ', response);
|
|
fail && fail(response);
|
|
}
|
|
}
|
|
};
|
|
xhr.timeout = 3000;
|
|
xhr.ontimeout = function (event) {
|
|
console.error('error ', event);
|
|
fail && fail(event);
|
|
};
|
|
xhr.open(method, url, true);
|
|
if (method == 'POST') {
|
|
const object2Query = function (obj) {
|
|
const args = [];
|
|
for (const k in obj) {
|
|
args.push(k + '=' + obj[k]);
|
|
}
|
|
return args.join('&');
|
|
};
|
|
|
|
xhr.open('POST', url);
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
xhr.send(object2Query(data));
|
|
} else {
|
|
xhr.send();
|
|
}
|
|
}
|
|
}
|
|
|