feat: 接入激励视频
This commit is contained in:
@@ -10,6 +10,7 @@ export class AudioManager {
|
||||
private _clickAudio: AudioClip | null = null;
|
||||
private _hostNode: Node | null = null;
|
||||
private _audioSource: AudioSource | null = null;
|
||||
private _pausedAudioSources: AudioSource[] = [];
|
||||
|
||||
static get instance(): AudioManager {
|
||||
if (!this._instance) {
|
||||
@@ -30,6 +31,34 @@ export class AudioManager {
|
||||
this._playOneShot(this._clickAudio);
|
||||
}
|
||||
|
||||
pausePlayingAudioSources(): void {
|
||||
if (!this._hostNode?.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._pausedAudioSources = [];
|
||||
const audioSources = this._hostNode.getComponentsInChildren(AudioSource);
|
||||
audioSources.forEach((audioSource) => {
|
||||
if (!audioSource?.isValid || !audioSource.playing) {
|
||||
return;
|
||||
}
|
||||
|
||||
audioSource.pause();
|
||||
this._pausedAudioSources.push(audioSource);
|
||||
});
|
||||
}
|
||||
|
||||
resumePausedAudioSources(): void {
|
||||
const pausedAudioSources = this._pausedAudioSources;
|
||||
this._pausedAudioSources = [];
|
||||
|
||||
pausedAudioSources.forEach((audioSource) => {
|
||||
if (audioSource?.isValid && !audioSource.playing) {
|
||||
audioSource.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _playOneShot(clip: AudioClip | null): void {
|
||||
if (!clip) {
|
||||
return;
|
||||
|
||||
@@ -34,6 +34,9 @@ export interface WxPrivacySettingResult {
|
||||
* 封装微信平台相关 API,非微信环境下静默降级
|
||||
*/
|
||||
export class WxSDK {
|
||||
/** 默认激励视频广告位 */
|
||||
private static readonly DEFAULT_REWARDED_VIDEO_AD_UNIT_ID = 'adunit-52a53828d4b91fe2';
|
||||
|
||||
/** 隐私授权请求进行中时复用同一个 Promise,避免启动链路重复弹窗 */
|
||||
private static _privacyAuthorizePromise: Promise<boolean> | null = null;
|
||||
|
||||
@@ -315,6 +318,12 @@ export class WxSDK {
|
||||
/** 激励视频广告实例(复用) */
|
||||
private static _rewardedVideoAd: any = null;
|
||||
|
||||
/** 当前复用实例对应的广告位 */
|
||||
private static _rewardedVideoAdUnitId: string = '';
|
||||
|
||||
/** 激励视频广告展示中的 Promise,避免重复拉起 */
|
||||
private static _rewardedVideoAdPromise: Promise<boolean> | null = null;
|
||||
|
||||
/**
|
||||
* 展示激励视频广告
|
||||
* 用户看完广告后返回 true,中途退出或失败返回 false
|
||||
@@ -322,68 +331,98 @@ export class WxSDK {
|
||||
* @param adUnitId 广告单元 ID(默认使用项目配置的 ID)
|
||||
* @returns Promise<boolean> 是否看完广告
|
||||
*/
|
||||
static showRewardedVideoAd(adUnitId: string = ''): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
const wxApi = WxSDK.getWx();
|
||||
if (!wxApi) {
|
||||
console.log('[WxSDK] 非微信环境,跳过激励视频广告');
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
static showRewardedVideoAd(adUnitId: string = WxSDK.DEFAULT_REWARDED_VIDEO_AD_UNIT_ID): Promise<boolean> {
|
||||
if (WxSDK._rewardedVideoAdPromise) {
|
||||
return WxSDK._rewardedVideoAdPromise;
|
||||
}
|
||||
|
||||
if (typeof wxApi.createRewardedVideoAd !== 'function') {
|
||||
console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
const wxApi = WxSDK.getWx();
|
||||
if (!wxApi) {
|
||||
console.log('[WxSDK] 非微信环境,跳过激励视频广告');
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
if (typeof wxApi.createRewardedVideoAd !== 'function') {
|
||||
console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
const resolvedAdUnitId = adUnitId || WxSDK.DEFAULT_REWARDED_VIDEO_AD_UNIT_ID;
|
||||
if (!resolvedAdUnitId) {
|
||||
console.warn('[WxSDK] 激励视频广告位未配置');
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
WxSDK._rewardedVideoAdPromise = new Promise((resolve) => {
|
||||
let ad: any = null;
|
||||
let finished = false;
|
||||
|
||||
const cleanup = () => {
|
||||
if (!ad) return;
|
||||
if (typeof ad.offClose === 'function') {
|
||||
ad.offClose(onClose);
|
||||
}
|
||||
if (typeof ad.offError === 'function') {
|
||||
ad.offError(onError);
|
||||
}
|
||||
};
|
||||
|
||||
const finish = (result: boolean) => {
|
||||
if (finished) return;
|
||||
finished = true;
|
||||
cleanup();
|
||||
WxSDK._rewardedVideoAdPromise = null;
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
const onClose = (res: any) => {
|
||||
const isEnded = res === undefined || !!res?.isEnded;
|
||||
if (isEnded) {
|
||||
console.log('[WxSDK] 激励视频广告观看完成');
|
||||
finish(true);
|
||||
} else {
|
||||
console.log('[WxSDK] 激励视频广告中途退出');
|
||||
finish(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onError = (err: any) => {
|
||||
console.error('[WxSDK] 激励视频广告错误:', err);
|
||||
finish(false);
|
||||
};
|
||||
|
||||
try {
|
||||
// 复用或创建广告实例
|
||||
if (!WxSDK._rewardedVideoAd) {
|
||||
WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({
|
||||
adUnitId: adUnitId,
|
||||
});
|
||||
}
|
||||
|
||||
const ad = WxSDK._rewardedVideoAd;
|
||||
|
||||
// 定义关闭回调(一次性)
|
||||
const onClose = (res: any) => {
|
||||
ad.offClose(onClose);
|
||||
if (res && res.isEnded) {
|
||||
console.log('[WxSDK] 激励视频广告观看完成');
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log('[WxSDK] 激励视频广告中途退出');
|
||||
resolve(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 定义错误回调(一次性)
|
||||
const onError = (err: any) => {
|
||||
ad.offError(onError);
|
||||
ad.offClose(onClose);
|
||||
console.error('[WxSDK] 激励视频广告错误:', err);
|
||||
resolve(false);
|
||||
};
|
||||
|
||||
ad = WxSDK.getRewardedVideoAd(wxApi, resolvedAdUnitId);
|
||||
ad.onClose(onClose);
|
||||
ad.onError(onError);
|
||||
|
||||
// 先尝试 show,如果广告未加载则先 load
|
||||
ad.show().catch(() => {
|
||||
ad.load().then(() => ad.show()).catch((loadErr: any) => {
|
||||
ad.offClose(onClose);
|
||||
ad.offError(onError);
|
||||
Promise.resolve(ad.show()).catch(() => {
|
||||
Promise.resolve(ad.load()).then(() => ad.show()).catch((loadErr: any) => {
|
||||
console.error('[WxSDK] 激励视频广告加载失败:', loadErr);
|
||||
resolve(false);
|
||||
finish(false);
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('[WxSDK] 激励视频广告异常:', err);
|
||||
resolve(false);
|
||||
finish(false);
|
||||
}
|
||||
});
|
||||
|
||||
return WxSDK._rewardedVideoAdPromise;
|
||||
}
|
||||
|
||||
private static getRewardedVideoAd(wxApi: any, adUnitId: string): any {
|
||||
if (WxSDK._rewardedVideoAd && WxSDK._rewardedVideoAdUnitId === adUnitId) {
|
||||
return WxSDK._rewardedVideoAd;
|
||||
}
|
||||
|
||||
if (WxSDK._rewardedVideoAd && typeof WxSDK._rewardedVideoAd.destroy === 'function') {
|
||||
WxSDK._rewardedVideoAd.destroy();
|
||||
}
|
||||
|
||||
WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({ adUnitId });
|
||||
WxSDK._rewardedVideoAdUnitId = adUnitId;
|
||||
return WxSDK._rewardedVideoAd;
|
||||
}
|
||||
|
||||
// ==================== 启动参数 ====================
|
||||
|
||||
Reference in New Issue
Block a user