reze-engine 0.3.2 → 0.3.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAGnC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAChC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,MAAM;IAEjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAwE;IAC1F,OAAO,CAAC,WAAW,CAA0E;IAC7F,OAAO,CAAC,QAAQ,CAAY;IAG5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,cAAc,CAAY;IAGlC,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAiB;IAEpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3C;;OAEG;IACH,OAAO,CAAC,aAAa;IAwErB;;OAEG;IACH,IAAI,IAAI,IAAI;IAyBZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBxB;;;OAGG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAiCrD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IA+I1C;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAQhC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAGnC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAChC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,MAAM;IAEjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAwE;IAC1F,OAAO,CAAC,WAAW,CAA0E;IAC7F,OAAO,CAAC,QAAQ,CAAY;IAG5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,cAAc,CAAY;IAGlC,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAiB;IAEpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C3C;;OAEG;IACH,OAAO,CAAC,aAAa;IAwErB;;OAEG;IACH,IAAI,IAAI,IAAI;IAoCZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBxB;;;OAGG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAiCrD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IA+I1C;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAQhC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}
package/dist/player.js CHANGED
@@ -39,6 +39,20 @@ export class Player {
39
39
  return new Promise((resolve, reject) => {
40
40
  const audio = new Audio(url);
41
41
  audio.preload = "auto";
42
+ // iOS Safari requires playsinline attribute for inline playback
43
+ // This must be set before loading
44
+ audio.setAttribute("playsinline", "true");
45
+ audio.setAttribute("webkit-playsinline", "true");
46
+ // Set volume to ensure audio is ready
47
+ audio.volume = 1.0;
48
+ // iOS sometimes requires audio element to be in DOM
49
+ // Add it hidden to the document body
50
+ audio.style.display = "none";
51
+ audio.style.position = "absolute";
52
+ audio.style.visibility = "hidden";
53
+ audio.style.width = "0";
54
+ audio.style.height = "0";
55
+ document.body.appendChild(audio);
42
56
  audio.addEventListener("loadeddata", () => {
43
57
  this.audioElement = audio;
44
58
  this.audioLoaded = true;
@@ -47,6 +61,10 @@ export class Player {
47
61
  audio.addEventListener("error", (e) => {
48
62
  console.warn("Failed to load audio:", url, e);
49
63
  this.audioLoaded = false;
64
+ // Remove from DOM on error
65
+ if (audio.parentNode) {
66
+ audio.parentNode.removeChild(audio);
67
+ }
50
68
  // Don't reject - animation should still work without audio
51
69
  resolve();
52
70
  });
@@ -140,10 +158,19 @@ export class Player {
140
158
  this.isPlaying = true;
141
159
  // Play audio if available
142
160
  if (this.audioElement && this.audioLoaded) {
161
+ // Ensure audio is ready for iOS
143
162
  this.audioElement.currentTime = this.currentTime;
144
- this.audioElement.play().catch((error) => {
145
- console.warn("Audio play failed:", error);
146
- });
163
+ this.audioElement.muted = false;
164
+ this.audioElement.volume = 1.0;
165
+ // iOS requires play() to be called synchronously during user interaction
166
+ // This must happen directly from the user's click/touch event
167
+ const playPromise = this.audioElement.play();
168
+ if (playPromise !== undefined) {
169
+ playPromise.catch((error) => {
170
+ // Log error but don't block animation playback
171
+ console.warn("Audio play failed:", error, error.name);
172
+ });
173
+ }
147
174
  }
148
175
  }
149
176
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "A WebGPU-based MMD model renderer",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/player.ts CHANGED
@@ -61,6 +61,23 @@ export class Player {
61
61
  const audio = new Audio(url)
62
62
  audio.preload = "auto"
63
63
 
64
+ // iOS Safari requires playsinline attribute for inline playback
65
+ // This must be set before loading
66
+ audio.setAttribute("playsinline", "true")
67
+ audio.setAttribute("webkit-playsinline", "true")
68
+
69
+ // Set volume to ensure audio is ready
70
+ audio.volume = 1.0
71
+
72
+ // iOS sometimes requires audio element to be in DOM
73
+ // Add it hidden to the document body
74
+ audio.style.display = "none"
75
+ audio.style.position = "absolute"
76
+ audio.style.visibility = "hidden"
77
+ audio.style.width = "0"
78
+ audio.style.height = "0"
79
+ document.body.appendChild(audio)
80
+
64
81
  audio.addEventListener("loadeddata", () => {
65
82
  this.audioElement = audio
66
83
  this.audioLoaded = true
@@ -70,6 +87,10 @@ export class Player {
70
87
  audio.addEventListener("error", (e) => {
71
88
  console.warn("Failed to load audio:", url, e)
72
89
  this.audioLoaded = false
90
+ // Remove from DOM on error
91
+ if (audio.parentNode) {
92
+ audio.parentNode.removeChild(audio)
93
+ }
73
94
  // Don't reject - animation should still work without audio
74
95
  resolve()
75
96
  })
@@ -174,10 +195,21 @@ export class Player {
174
195
 
175
196
  // Play audio if available
176
197
  if (this.audioElement && this.audioLoaded) {
198
+ // Ensure audio is ready for iOS
177
199
  this.audioElement.currentTime = this.currentTime
178
- this.audioElement.play().catch((error) => {
179
- console.warn("Audio play failed:", error)
180
- })
200
+ this.audioElement.muted = false
201
+ this.audioElement.volume = 1.0
202
+
203
+ // iOS requires play() to be called synchronously during user interaction
204
+ // This must happen directly from the user's click/touch event
205
+ const playPromise = this.audioElement.play()
206
+
207
+ if (playPromise !== undefined) {
208
+ playPromise.catch((error) => {
209
+ // Log error but don't block animation playback
210
+ console.warn("Audio play failed:", error, error.name)
211
+ })
212
+ }
181
213
  }
182
214
  }
183
215