未验证 提交 1a9b2322 编写于 作者: B bofeng-song 提交者: GitHub

fix audio can not reset to position 0 after call stop operation on web platform (#16122)

* fix audio can not reset to position 0 after call stop operation on web platform
上级 aa3b35e9
......@@ -25,6 +25,7 @@
import { minigame } from 'pal/minigame';
import { systemInfo } from 'pal/system-info';
import { clamp01 } from '../../../cocos/core';
import * as debug from '../../../cocos/core/platform/debug';
import { EventTarget } from '../../../cocos/core/event';
import { audioBufferManager } from '../audio-buffer-manager';
import AudioTimer from '../audio-timer';
......@@ -133,7 +134,7 @@ export class AudioPlayerWeb implements OperationQueueable {
this._state = AudioState.INTERRUPTED;
this._readyToHandleOnShow = true;
this._eventTarget.emit(AudioEvent.INTERRUPTION_BEGIN);
}).catch((e) => {});
}).catch((e) => { debug.warn('_onInterruptedBegin error', e); });
}
}
private _onInterruptedEnd (): void {
......@@ -145,7 +146,7 @@ export class AudioPlayerWeb implements OperationQueueable {
if (this._state === AudioState.INTERRUPTED) {
this.play().then(() => {
this._eventTarget.emit(AudioEvent.INTERRUPTION_END);
}).catch((e) => {});
}).catch((e) => { debug.warn('_onInterruptedEnd error', e); });
}
this._readyToHandleOnShow = false;
}
......@@ -153,7 +154,7 @@ export class AudioPlayerWeb implements OperationQueueable {
return new Promise((resolve) => {
AudioPlayerWeb.loadNative(url).then((audioBuffer) => {
resolve(new AudioPlayerWeb(audioBuffer, url));
}).catch((e) => {});
}).catch((e) => { debug.warn('load error', url, e); });
});
}
static loadNative (url: string): Promise<AudioBuffer> {
......@@ -175,7 +176,7 @@ export class AudioPlayerWeb implements OperationQueueable {
audioContext!.decodeAudioData(arrayBuffer).then((decodedAudioBuffer) => {
audioBufferManager.addCache(url, decodedAudioBuffer);
resolve(decodedAudioBuffer);
}).catch((e) => {});
}).catch((e) => { debug.warn('loadNative error', url, e); });
});
});
}
......@@ -185,6 +186,7 @@ export class AudioPlayerWeb implements OperationQueueable {
AudioPlayerWeb.loadNative(url).then((audioBuffer) => {
// HACK: AudioPlayer should be a friend class in OneShotAudio
const oneShotAudio = new (OneShotAudioWeb as any)(audioBuffer, volume, url);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
resolve(oneShotAudio);
}).catch(reject);
});
......@@ -238,7 +240,7 @@ export class AudioPlayerWeb implements OperationQueueable {
if (this._state === AudioState.PLAYING) {
// one AudioBufferSourceNode can't start twice
// need to create a new one to start from the offset
this._doPlay().then(resolve).catch((e) => {});
this._doPlay().then(resolve).catch((e) => { debug.warn('seek error', e); });
} else {
resolve();
}
......@@ -302,6 +304,8 @@ export class AudioPlayerWeb implements OperationQueueable {
@enqueueOperation
stop (): Promise<void> {
if (!this._sourceNode) {
this._audioTimer.stop();
this._state = AudioState.STOPPED;
return Promise.resolve();
}
this._audioTimer.stop();
......
......@@ -26,6 +26,7 @@ import { EDITOR_NOT_IN_PREVIEW } from 'internal:constants';
import { AudioPCMDataView, AudioEvent, AudioState, AudioType } from '../type';
import { EventTarget } from '../../../cocos/core/event';
import { clamp01 } from '../../../cocos/core';
import * as debug from '../../../cocos/core/platform/debug';
import { enqueueOperation, OperationInfo, OperationQueueable } from '../operation-queue';
import AudioTimer from '../audio-timer';
import { audioBufferManager } from '../audio-buffer-manager';
......@@ -76,9 +77,10 @@ export class AudioContextAgent {
resolve(audioBuffer);
}, (err) => {
// TODO: need to reject the error.
// eslint-disable-next-line no-console
console.error('failed to load Web Audio', err);
});
promise?.catch((e) => {}); // Safari doesn't support the promise based decodeAudioData
promise?.catch((e) => { debug.warn('decodeAudioData error', e); }); // Safari doesn't support the promise based decodeAudioData
});
}
......@@ -93,7 +95,7 @@ export class AudioContextAgent {
resolve();
return;
}
context.resume().catch((e) => {});
context.resume().catch((e) => { debug.warn('runContext error', e); });
if (context.state === 'running') {
resolve();
return;
......@@ -106,7 +108,7 @@ export class AudioContextAgent {
canvas?.removeEventListener('touchend', onGesture, { capture: true });
canvas?.removeEventListener('mouseup', onGesture, { capture: true });
resolve();
}).catch((e) => {});
}).catch((e) => { debug.warn('onGesture resume error', e); });
};
canvas?.addEventListener('touchend', onGesture, { capture: true });
canvas?.addEventListener('mouseup', onGesture, { capture: true });
......@@ -199,7 +201,7 @@ export class OneShotAudioWeb {
audioBufferManager.tryReleasingCache(this._url);
this.onEnd?.();
}, this._duration * 1000);
}).catch((e) => {});
}).catch((e) => { debug.warn('play error', e); });
}
public stop (): void {
......@@ -257,7 +259,7 @@ export class AudioPlayerWeb implements OperationQueueable {
return new Promise((resolve) => {
AudioPlayerWeb.loadNative(url).then((audioBuffer) => {
resolve(new AudioPlayerWeb(audioBuffer, url));
}).catch((e) => {});
}).catch((e) => { debug.warn('load error', url, e); });
});
}
static loadNative (url: string): Promise<AudioBuffer> {
......@@ -275,10 +277,11 @@ export class AudioPlayerWeb implements OperationQueueable {
xhr.onload = (): void => {
if (xhr.status === 200 || xhr.status === 0) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
audioContextAgent!.decodeAudioData(xhr.response).then((decodedAudioBuffer) => {
audioBufferManager.addCache(url, decodedAudioBuffer);
resolve(decodedAudioBuffer);
}).catch((e) => {});
}).catch((e) => { debug.warn('loadNative error', url, e); });
} else {
reject(new Error(`${errInfo}${xhr.status}(no response)`));
}
......@@ -295,6 +298,7 @@ export class AudioPlayerWeb implements OperationQueueable {
AudioPlayerWeb.loadNative(url).then((audioBuffer) => {
// HACK: AudioPlayer should be a friend class in OneShotAudio
const oneShotAudio = new (OneShotAudioWeb as any)(audioBuffer, volume, url);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
resolve(oneShotAudio);
}).catch(reject);
});
......@@ -313,14 +317,14 @@ export class AudioPlayerWeb implements OperationQueueable {
this.pause().then(() => {
this._state = AudioState.INTERRUPTED;
this._eventTarget.emit(AudioEvent.INTERRUPTION_BEGIN);
}).catch((e) => {});
}).catch((e) => { debug.warn('_onInterruptedBegin error', e); });
}
}
private _onInterruptedEnd (): void {
if (this._state === AudioState.INTERRUPTED) {
this.play().then(() => {
this._eventTarget.emit(AudioEvent.INTERRUPTION_END);
}).catch((e) => {});
}).catch((e) => { debug.warn('_onInterruptedEnd error', e); });
}
}
......@@ -371,7 +375,7 @@ export class AudioPlayerWeb implements OperationQueueable {
if (this._state === AudioState.PLAYING) {
// one AudioBufferSourceNode can't start twice
// need to create a new one to start from the offset
this._doPlay().then(resolve).catch((e) => {});
this._doPlay().then(resolve).catch((e) => { debug.warn('seek error', e); });
} else {
resolve();
}
......@@ -405,7 +409,7 @@ export class AudioPlayerWeb implements OperationQueueable {
// - system automatically resume audio context when enter foreground from background.
audioContextAgent!.onceRunning(this._runningCallback);
// Ensure resume context.
audioContextAgent!.runContext().catch((e) => {});
audioContextAgent!.runContext().catch((e) => { debug.warn('doPlay error', e); });
}
});
}
......@@ -415,6 +419,7 @@ export class AudioPlayerWeb implements OperationQueueable {
this._stopSourceNode();
this._sourceNode = audioContextAgent!.createBufferSource(this._audioBuffer, this.loop);
this._sourceNode.connect(this._gainNode);
this._sourceNode.loop = this._loop;
this._sourceNode.start(0, this._audioTimer.currentTime);
this._state = AudioState.PLAYING;
this._audioTimer.start();
......@@ -465,6 +470,8 @@ export class AudioPlayerWeb implements OperationQueueable {
stop (): Promise<void> {
this.offRunning();
if (!this._sourceNode) {
this._audioTimer.stop();
this._state = AudioState.STOPPED;
return Promise.resolve();
}
this._audioTimer.stop();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册