@galacean/engine-core 1.6.12 → 1.6.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -36909,22 +36909,32 @@ var cacheDir = new engineMath.Vector3();
36909
36909
  }(ReferResource);
36910
36910
 
36911
36911
  /**
36912
- * @internal
36913
- * Audio Manager.
36912
+ * Audio Manager for managing global audio context and settings.
36914
36913
  */ var AudioManager = /*#__PURE__*/ function() {
36915
36914
  function AudioManager() {}
36916
- AudioManager.getContext = function getContext() {
36915
+ /**
36916
+ * Resume the audio context.
36917
+ * @remarks On iOS Safari, calling this within a user gesture (e.g., click/touch event handler) can pre-unlock audio and reduce playback delay.
36918
+ * @returns A promise that resolves when the audio context is resumed
36919
+ */ AudioManager.resume = function resume() {
36920
+ var _AudioManager;
36921
+ var __resumePromise;
36922
+ return (__resumePromise = (_AudioManager = AudioManager)._resumePromise) != null ? __resumePromise : _AudioManager._resumePromise = AudioManager._context.resume().finally(function() {
36923
+ AudioManager._resumePromise = null;
36924
+ });
36925
+ };
36926
+ /**
36927
+ * @internal
36928
+ */ AudioManager.getContext = function getContext() {
36917
36929
  var context = AudioManager._context;
36918
36930
  if (!context) {
36919
36931
  AudioManager._context = context = new window.AudioContext();
36920
- // Safari can't resume audio context without element interaction
36921
- document.addEventListener("pointerdown", AudioManager._tryResume, true);
36922
- document.addEventListener("touchend", AudioManager._tryResume, true);
36923
- document.addEventListener("touchstart", AudioManager._tryResume, true);
36924
36932
  }
36925
36933
  return context;
36926
36934
  };
36927
- AudioManager.getGainNode = function getGainNode() {
36935
+ /**
36936
+ * @internal
36937
+ */ AudioManager.getGainNode = function getGainNode() {
36928
36938
  var gainNode = AudioManager._gainNode;
36929
36939
  if (!AudioManager._gainNode) {
36930
36940
  AudioManager._gainNode = gainNode = AudioManager.getContext().createGain();
@@ -36932,27 +36942,14 @@ var cacheDir = new engineMath.Vector3();
36932
36942
  }
36933
36943
  return gainNode;
36934
36944
  };
36935
- AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36936
- if (AudioManager.getContext().state !== "running") {
36937
- console.warn("The AudioContext is not running and requires user interaction, such as a click or touch.");
36938
- return false;
36939
- }
36940
- return true;
36941
- };
36942
- AudioManager._tryResume = function _tryResume() {
36943
- if (AudioManager._context.state !== "running") {
36944
- if (AudioManager._isResuming) {
36945
- return;
36946
- }
36947
- AudioManager._isResuming = true;
36948
- AudioManager._context.resume().then(function() {
36949
- AudioManager._isResuming = false;
36950
- });
36951
- }
36945
+ /**
36946
+ * @internal
36947
+ */ AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36948
+ return AudioManager.getContext().state === "running";
36952
36949
  };
36953
36950
  return AudioManager;
36954
36951
  }();
36955
- AudioManager._isResuming = false;
36952
+ AudioManager._resumePromise = null;
36956
36953
 
36957
36954
  /**
36958
36955
  * Audio Source Component.
@@ -36960,7 +36957,7 @@ AudioManager._isResuming = false;
36960
36957
  _inherits(AudioSource, Component);
36961
36958
  function AudioSource(entity) {
36962
36959
  var _this;
36963
- _this = Component.call(this, entity) || this, /** If set to true, the audio component automatically begins to play on startup. */ _this.playOnEnabled = true, _this._isPlaying = false, _this._sourceNode = null, _this._pausedTime = -1, _this._playTime = -1, _this._volume = 1, _this._lastVolume = 1, _this._playbackRate = 1, _this._loop = false;
36960
+ _this = Component.call(this, entity) || this, /** If set to true, the audio component automatically begins to play on startup. */ _this.playOnEnabled = true, _this._isPlaying = false, _this._pendingPlay = false, _this._sourceNode = null, _this._pausedTime = -1, _this._playTime = -1, _this._volume = 1, _this._lastVolume = 1, _this._playbackRate = 1, _this._loop = false;
36964
36961
  _this._onPlayEnd = _this._onPlayEnd.bind(_this);
36965
36962
  _this._gainNode = AudioManager.getContext().createGain();
36966
36963
  _this._gainNode.connect(AudioManager.getGainNode());
@@ -36970,21 +36967,37 @@ AudioManager._isResuming = false;
36970
36967
  /**
36971
36968
  * Play the clip.
36972
36969
  */ _proto.play = function play() {
36973
- if (!this._canPlay()) {
36970
+ var _this = this;
36971
+ var _this__clip;
36972
+ if (!((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource())) {
36974
36973
  return;
36975
36974
  }
36976
- if (this._isPlaying) {
36975
+ if (this._isPlaying || this._pendingPlay) {
36977
36976
  return;
36978
36977
  }
36979
- var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
36980
- this._initSourceNode(startTime);
36981
- this._playTime = AudioManager.getContext().currentTime - startTime;
36982
- this._pausedTime = -1;
36983
- this._isPlaying = true;
36978
+ if (AudioManager.isAudioContextRunning()) {
36979
+ this._startPlayback();
36980
+ } else {
36981
+ // iOS Safari requires resume() to be called within the same user gesture callback that triggers playback.
36982
+ // Document-level events won't work - must call resume() directly here in play().
36983
+ this._pendingPlay = true;
36984
+ AudioManager.resume().then(function() {
36985
+ _this._pendingPlay = false;
36986
+ // Check if still valid to play after async resume
36987
+ if (_this._destroyed || !_this.enabled || !_this._clip) {
36988
+ return;
36989
+ }
36990
+ _this._startPlayback();
36991
+ }, function(e) {
36992
+ _this._pendingPlay = false;
36993
+ console.warn("AudioContext resume failed:", e);
36994
+ });
36995
+ }
36984
36996
  };
36985
36997
  /**
36986
36998
  * Stops playing the clip.
36987
36999
  */ _proto.stop = function stop() {
37000
+ this._pendingPlay = false;
36988
37001
  if (this._isPlaying) {
36989
37002
  this._clearSourceNode();
36990
37003
  this._isPlaying = false;
@@ -36995,6 +37008,7 @@ AudioManager._isResuming = false;
36995
37008
  /**
36996
37009
  * Pauses playing the clip.
36997
37010
  */ _proto.pause = function pause() {
37011
+ this._pendingPlay = false;
36998
37012
  if (this._isPlaying) {
36999
37013
  this._clearSourceNode();
37000
37014
  this._pausedTime = AudioManager.getContext().currentTime;
@@ -37028,6 +37042,13 @@ AudioManager._isResuming = false;
37028
37042
  _proto._onPlayEnd = function _onPlayEnd() {
37029
37043
  this.stop();
37030
37044
  };
37045
+ _proto._startPlayback = function _startPlayback() {
37046
+ var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
37047
+ this._initSourceNode(startTime);
37048
+ this._playTime = AudioManager.getContext().currentTime - startTime;
37049
+ this._pausedTime = -1;
37050
+ this._isPlaying = true;
37051
+ };
37031
37052
  _proto._initSourceNode = function _initSourceNode(startTime) {
37032
37053
  var context = AudioManager.getContext();
37033
37054
  var sourceNode = context.createBufferSource();
@@ -37045,11 +37066,6 @@ AudioManager._isResuming = false;
37045
37066
  this._sourceNode.onended = null;
37046
37067
  this._sourceNode = null;
37047
37068
  };
37048
- _proto._canPlay = function _canPlay() {
37049
- var _this__clip;
37050
- var isValidClip = ((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource()) ? true : false;
37051
- return isValidClip && AudioManager.isAudioContextRunning();
37052
- };
37053
37069
  _create_class(AudioSource, [
37054
37070
  {
37055
37071
  key: "clip",
@@ -37158,6 +37174,9 @@ AudioManager._isResuming = false;
37158
37174
  __decorate([
37159
37175
  ignoreClone
37160
37176
  ], AudioSource.prototype, "_isPlaying", void 0);
37177
+ __decorate([
37178
+ ignoreClone
37179
+ ], AudioSource.prototype, "_pendingPlay", void 0);
37161
37180
  __decorate([
37162
37181
  assignmentClone
37163
37182
  ], AudioSource.prototype, "_clip", void 0);