Skip to content

Commit

Permalink
refine: erase unneed audio operation & fix some potential bug
Browse files Browse the repository at this point in the history
  • Loading branch information
bofeng-song committed Aug 7, 2023
1 parent a907d68 commit 98463f6
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 20 deletions.
43 changes: 28 additions & 15 deletions cocos/audio/audio-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ enum AudioSourceEventType {
ENDED = 'ended',
}

class OperationInfo {
op: string = '';
params: any;
}

/**
* @en
* A representation of a single audio source, <br>
Expand Down Expand Up @@ -68,10 +73,10 @@ export class AudioSource extends Component {
@serializable
protected _volume = 1;

private _cachedCurrentTime = 0;
private _cachedCurrentTime = -1;

// An operation queue to store the operations before loading the AudioPlayer.
private _operationsBeforeLoading: string[] = [];
private _operationsBeforeLoading: OperationInfo[] = [];
private _isLoaded = false;

private _lastSetClip: AudioClip | null = null;
Expand Down Expand Up @@ -345,7 +350,7 @@ export class AudioSource extends Component {
*/
public play (): void {
if (!this._isLoaded && this.clip) {
this._operationsBeforeLoading.push('play');
this._operationsBeforeLoading.push({ op: 'play', params: null });
return;
}
this._registerListener();
Expand Down Expand Up @@ -373,7 +378,7 @@ export class AudioSource extends Component {
*/
public pause (): void {
if (!this._isLoaded && this.clip) {
this._operationsBeforeLoading.push('pause');
this._operationsBeforeLoading.push({ op: 'pause', params: null });
return;
}
this._player?.pause().catch((e) => {});

Check failure on line 384 in cocos/audio/audio-source.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected empty arrow function
Expand All @@ -387,7 +392,7 @@ export class AudioSource extends Component {
*/
public stop (): void {
if (!this._isLoaded && this.clip) {
this._operationsBeforeLoading.push('stop');
this._operationsBeforeLoading.push({ op: 'stop', params: null });
return;
}
if (this._player) {
Expand Down Expand Up @@ -428,15 +433,19 @@ export class AudioSource extends Component {
}

protected _syncStates (): void {
if (!this._player) { return; }
this._player.seek(this._cachedCurrentTime).then((): void => {
if (this._player) {
this._player.loop = this._loop;
this._player.volume = this._volume;
this._operationsBeforeLoading.forEach((opName): void => { this[opName]?.(); });
this._operationsBeforeLoading.length = 0;
}
}).catch((e): void => {});
if (this._player) {
this._player.loop = this._loop;
this._player.volume = this._volume;
this._operationsBeforeLoading.forEach((opInfo): void => {
if (opInfo.op === 'seek') {
this._cachedCurrentTime = opInfo.params as number;
this._player?.seek(this._cachedCurrentTime).catch((e): void => {});

Check failure on line 442 in cocos/audio/audio-source.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected empty arrow function
} else {
this[opInfo.op]?.();
}
});
this._operationsBeforeLoading.length = 0;
}
}

/**
Expand All @@ -449,6 +458,10 @@ export class AudioSource extends Component {
set currentTime (num: number) {
if (Number.isNaN(num)) { console.warn('illegal audio time!'); return; }

Check failure on line 459 in cocos/audio/audio-source.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected console statement
num = clamp(num, 0, this.duration);
if (!this._isLoaded && this.clip) {
this._operationsBeforeLoading.push({ op: 'seek', params: num });
return;
}
this._cachedCurrentTime = num;
this._player?.seek(this._cachedCurrentTime).catch((e): void => {});
}
Expand All @@ -460,7 +473,7 @@ export class AudioSource extends Component {
* 以秒为单位获取当前播放时间。
*/
get currentTime (): number {
return this._player ? this._player.currentTime : this._cachedCurrentTime;
return this._player ? this._player.currentTime : (this._cachedCurrentTime < 0 ? 0 : this._cachedCurrentTime);
}

/**
Expand Down
18 changes: 13 additions & 5 deletions pal/audio/minigame/player-minigame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class AudioPlayerMinigame implements OperationQueueable {
['Play', 'Pause', 'Stop', 'Seeked', 'Ended'].forEach((event) => {
this._offEvent(event);
});
// NOTE: innewAudioContext might not stop the audio playing, have to call it explicitly.
// NOTE: innerAudioContext might not stop the audio playing, have to call it explicitly.
this._innerAudioContext.stop();
this._innerAudioContext.destroy();
// NOTE: Type 'null' is not assignable to type 'InnerAudioContext'
Expand Down Expand Up @@ -318,12 +318,15 @@ export class AudioPlayerMinigame implements OperationQueueable {
if (this._state === AudioState.PLAYING && !this._seeking) {
time = clamp(time, 0, this.duration);
this._seeking = true;
this._eventTarget.once(AudioEvent.SEEKED, resolve);
this._innerAudioContext.seek(time);
} else if (this._cacheTime !== time) { // Skip the invalid seek
this._cacheTime = time;
this._needSeek = true;
} else {
if (this._cacheTime !== time) { // Skip the invalid seek
this._cacheTime = time;
this._needSeek = true;
}
resolve();
}
resolve();
});
}

Expand All @@ -350,6 +353,11 @@ export class AudioPlayerMinigame implements OperationQueueable {
@enqueueOperation
stop (): Promise<void> {
return new Promise((resolve) => {
if (AudioState.INIT === this._state) {
this._resetSeekCache();
resolve();
return;
}
this._eventTarget.once(AudioEvent.STOPPED, resolve);
this._innerAudioContext.stop();
});
Expand Down
35 changes: 35 additions & 0 deletions pal/audio/operation-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EventTarget } from '../../cocos/core';

type OperationMethod = (...args: any[]) => Promise<void>;
export interface OperationInfo {
op: string;
id: number;
func: OperationMethod;
args: any[],
Expand All @@ -37,6 +38,38 @@ export interface OperationQueueable {
_eventTarget: EventTarget;
}

function removeUnneededCalls (instance: OperationQueueable): void {
const size = instance._operationQueue.length;
const tmpQueue = instance._operationQueue.slice();
const reserveOps: OperationInfo[] = [];
let seekSearched = false;
for (let i = size - 1; i >= 0; i--) {
const opInfo = tmpQueue[i];
if (opInfo.op === 'stop') {
reserveOps.push(opInfo);
break;
} else if (opInfo.op === 'seek') {
if (!seekSearched) {
reserveOps.push(opInfo);
seekSearched = true;
}
} else if (seekSearched) {
reserveOps.push(opInfo);
break;
} else if (reserveOps.length === 0) {
reserveOps.push(opInfo);
}
}
reserveOps.forEach((opInfo): void => {
const index = instance._operationQueue.indexOf(opInfo);
instance._operationQueue.splice(index, 1);
});
instance._operationQueue.forEach((opInfo): void => {
instance._eventTarget.emit(opInfo.id.toString());
});
instance._operationQueue = reserveOps.reverse();
}

let operationId = 0;
function _tryCallingRecursively<T extends OperationQueueable> (target: T, opInfo: OperationInfo): void {
if (opInfo.invoking) {
Expand All @@ -47,6 +80,7 @@ function _tryCallingRecursively<T extends OperationQueueable> (target: T, opInfo
opInfo.invoking = false;
target._operationQueue.shift();
target._eventTarget.emit(opInfo.id.toString());
removeUnneededCalls(target);
const nextOpInfo: OperationInfo = target._operationQueue[0];
nextOpInfo && _tryCallingRecursively(target, nextOpInfo);

Check warning on line 85 in pal/audio/operation-queue.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Expected an assignment or function call and instead saw an expression
}).catch((e) => {});
Expand All @@ -72,6 +106,7 @@ export function enqueueOperation<T extends OperationQueueable> (target: T, prope
const instance = this as OperationQueueable;
// enqueue operation
instance._operationQueue.push({
op: propertyKey,
id,
func: originalOperation,
args,
Expand Down

0 comments on commit 98463f6

Please sign in to comment.