@@ -46,6 +46,7 @@ export class AudioPlayer {
46
46
}
47
47
48
48
const AudioContext =
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
50
window . AudioContext || ( window as any ) . webkitAudioContext ;
50
51
51
52
this . audioContext = new AudioContext ( ) ;
@@ -76,7 +77,7 @@ export class AudioPlayer {
76
77
const arrayBuffer = stringToArrayBuffer ( data ) ;
77
78
try {
78
79
await audioContext . decodeAudioData (
79
- arrayBuffer . buffer ,
80
+ toArrayBuffer ( arrayBuffer . buffer ) ,
80
81
this . scheduleChunk
81
82
) ;
82
83
} catch ( error ) {
@@ -127,6 +128,7 @@ export class AudioPlayer {
127
128
source . buffer = buffer ;
128
129
source . connect ( audioContext . destination ) ;
129
130
source . loop = false ;
131
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
130
132
source . onended = ( _ : Event ) => {
131
133
this . chunks . splice ( this . chunks . indexOf ( source ) , 1 ) ;
132
134
if ( this . chunks . length === 0 ) {
@@ -146,3 +148,27 @@ export class AudioPlayer {
146
148
) ;
147
149
}
148
150
}
151
+
152
+ function toArrayBuffer ( data : ArrayBufferLike ) : ArrayBuffer {
153
+ // (1) If it’s already an ArrayBuffer, just return it.
154
+ if ( data instanceof ArrayBuffer ) {
155
+ return data ;
156
+ }
157
+
158
+ // (2) If it’s a TypedArray or DataView, pull out the exact bytes.
159
+ if ( ArrayBuffer . isView ( data ) ) {
160
+ const view = data as ArrayBufferView ;
161
+ const buffer = view . buffer . slice (
162
+ view . byteOffset ,
163
+ view . byteOffset + view . byteLength
164
+ ) ;
165
+ if ( buffer instanceof SharedArrayBuffer ) {
166
+ return new Uint8Array ( data as SharedArrayBuffer ) . slice ( ) . buffer ;
167
+ }
168
+ return buffer ;
169
+ }
170
+
171
+ // (3) Otherwise it must be a SharedArrayBuffer — copy it into a new ArrayBuffer.
172
+ // We do this by wrapping in a Uint8Array and slicing.
173
+ return new Uint8Array ( data as SharedArrayBuffer ) . slice ( ) . buffer ;
174
+ }
0 commit comments