@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/module.js CHANGED
@@ -36905,22 +36905,32 @@ var cacheDir = new Vector3();
36905
36905
  }(ReferResource);
36906
36906
 
36907
36907
  /**
36908
- * @internal
36909
- * Audio Manager.
36908
+ * Audio Manager for managing global audio context and settings.
36910
36909
  */ var AudioManager = /*#__PURE__*/ function() {
36911
36910
  function AudioManager() {}
36912
- AudioManager.getContext = function getContext() {
36911
+ /**
36912
+ * Resume the audio context.
36913
+ * @remarks On iOS Safari, calling this within a user gesture (e.g., click/touch event handler) can pre-unlock audio and reduce playback delay.
36914
+ * @returns A promise that resolves when the audio context is resumed
36915
+ */ AudioManager.resume = function resume() {
36916
+ var _AudioManager;
36917
+ var __resumePromise;
36918
+ return (__resumePromise = (_AudioManager = AudioManager)._resumePromise) != null ? __resumePromise : _AudioManager._resumePromise = AudioManager._context.resume().finally(function() {
36919
+ AudioManager._resumePromise = null;
36920
+ });
36921
+ };
36922
+ /**
36923
+ * @internal
36924
+ */ AudioManager.getContext = function getContext() {
36913
36925
  var context = AudioManager._context;
36914
36926
  if (!context) {
36915
36927
  AudioManager._context = context = new window.AudioContext();
36916
- // Safari can't resume audio context without element interaction
36917
- document.addEventListener("pointerdown", AudioManager._tryResume, true);
36918
- document.addEventListener("touchend", AudioManager._tryResume, true);
36919
- document.addEventListener("touchstart", AudioManager._tryResume, true);
36920
36928
  }
36921
36929
  return context;
36922
36930
  };
36923
- AudioManager.getGainNode = function getGainNode() {
36931
+ /**
36932
+ * @internal
36933
+ */ AudioManager.getGainNode = function getGainNode() {
36924
36934
  var gainNode = AudioManager._gainNode;
36925
36935
  if (!AudioManager._gainNode) {
36926
36936
  AudioManager._gainNode = gainNode = AudioManager.getContext().createGain();
@@ -36928,27 +36938,14 @@ var cacheDir = new Vector3();
36928
36938
  }
36929
36939
  return gainNode;
36930
36940
  };
36931
- AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36932
- if (AudioManager.getContext().state !== "running") {
36933
- console.warn("The AudioContext is not running and requires user interaction, such as a click or touch.");
36934
- return false;
36935
- }
36936
- return true;
36937
- };
36938
- AudioManager._tryResume = function _tryResume() {
36939
- if (AudioManager._context.state !== "running") {
36940
- if (AudioManager._isResuming) {
36941
- return;
36942
- }
36943
- AudioManager._isResuming = true;
36944
- AudioManager._context.resume().then(function() {
36945
- AudioManager._isResuming = false;
36946
- });
36947
- }
36941
+ /**
36942
+ * @internal
36943
+ */ AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36944
+ return AudioManager.getContext().state === "running";
36948
36945
  };
36949
36946
  return AudioManager;
36950
36947
  }();
36951
- AudioManager._isResuming = false;
36948
+ AudioManager._resumePromise = null;
36952
36949
 
36953
36950
  /**
36954
36951
  * Audio Source Component.
@@ -36956,7 +36953,7 @@ AudioManager._isResuming = false;
36956
36953
  _inherits(AudioSource, Component);
36957
36954
  function AudioSource(entity) {
36958
36955
  var _this;
36959
- _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;
36956
+ _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;
36960
36957
  _this._onPlayEnd = _this._onPlayEnd.bind(_this);
36961
36958
  _this._gainNode = AudioManager.getContext().createGain();
36962
36959
  _this._gainNode.connect(AudioManager.getGainNode());
@@ -36966,21 +36963,37 @@ AudioManager._isResuming = false;
36966
36963
  /**
36967
36964
  * Play the clip.
36968
36965
  */ _proto.play = function play() {
36969
- if (!this._canPlay()) {
36966
+ var _this = this;
36967
+ var _this__clip;
36968
+ if (!((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource())) {
36970
36969
  return;
36971
36970
  }
36972
- if (this._isPlaying) {
36971
+ if (this._isPlaying || this._pendingPlay) {
36973
36972
  return;
36974
36973
  }
36975
- var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
36976
- this._initSourceNode(startTime);
36977
- this._playTime = AudioManager.getContext().currentTime - startTime;
36978
- this._pausedTime = -1;
36979
- this._isPlaying = true;
36974
+ if (AudioManager.isAudioContextRunning()) {
36975
+ this._startPlayback();
36976
+ } else {
36977
+ // iOS Safari requires resume() to be called within the same user gesture callback that triggers playback.
36978
+ // Document-level events won't work - must call resume() directly here in play().
36979
+ this._pendingPlay = true;
36980
+ AudioManager.resume().then(function() {
36981
+ _this._pendingPlay = false;
36982
+ // Check if still valid to play after async resume
36983
+ if (_this._destroyed || !_this.enabled || !_this._clip) {
36984
+ return;
36985
+ }
36986
+ _this._startPlayback();
36987
+ }, function(e) {
36988
+ _this._pendingPlay = false;
36989
+ console.warn("AudioContext resume failed:", e);
36990
+ });
36991
+ }
36980
36992
  };
36981
36993
  /**
36982
36994
  * Stops playing the clip.
36983
36995
  */ _proto.stop = function stop() {
36996
+ this._pendingPlay = false;
36984
36997
  if (this._isPlaying) {
36985
36998
  this._clearSourceNode();
36986
36999
  this._isPlaying = false;
@@ -36991,6 +37004,7 @@ AudioManager._isResuming = false;
36991
37004
  /**
36992
37005
  * Pauses playing the clip.
36993
37006
  */ _proto.pause = function pause() {
37007
+ this._pendingPlay = false;
36994
37008
  if (this._isPlaying) {
36995
37009
  this._clearSourceNode();
36996
37010
  this._pausedTime = AudioManager.getContext().currentTime;
@@ -37024,6 +37038,13 @@ AudioManager._isResuming = false;
37024
37038
  _proto._onPlayEnd = function _onPlayEnd() {
37025
37039
  this.stop();
37026
37040
  };
37041
+ _proto._startPlayback = function _startPlayback() {
37042
+ var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
37043
+ this._initSourceNode(startTime);
37044
+ this._playTime = AudioManager.getContext().currentTime - startTime;
37045
+ this._pausedTime = -1;
37046
+ this._isPlaying = true;
37047
+ };
37027
37048
  _proto._initSourceNode = function _initSourceNode(startTime) {
37028
37049
  var context = AudioManager.getContext();
37029
37050
  var sourceNode = context.createBufferSource();
@@ -37041,11 +37062,6 @@ AudioManager._isResuming = false;
37041
37062
  this._sourceNode.onended = null;
37042
37063
  this._sourceNode = null;
37043
37064
  };
37044
- _proto._canPlay = function _canPlay() {
37045
- var _this__clip;
37046
- var isValidClip = ((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource()) ? true : false;
37047
- return isValidClip && AudioManager.isAudioContextRunning();
37048
- };
37049
37065
  _create_class(AudioSource, [
37050
37066
  {
37051
37067
  key: "clip",
@@ -37154,6 +37170,9 @@ AudioManager._isResuming = false;
37154
37170
  __decorate([
37155
37171
  ignoreClone
37156
37172
  ], AudioSource.prototype, "_isPlaying", void 0);
37173
+ __decorate([
37174
+ ignoreClone
37175
+ ], AudioSource.prototype, "_pendingPlay", void 0);
37157
37176
  __decorate([
37158
37177
  assignmentClone
37159
37178
  ], AudioSource.prototype, "_clip", void 0);