react-native-audiosprites 0.4.1 → 0.5.0
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/README.md +432 -6
- package/lib/module/index.js +85 -7
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +42 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/index.tsx +114 -8
package/README.md
CHANGED
|
@@ -27,6 +27,20 @@ audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg
|
|
|
27
27
|
|
|
28
28
|
This command will generate `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a`, and `mygameaudio.ac3` in the `src/__tests__/sounds/` directory.
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* ⚠️ ANDROID RESOURCE CONFLICT FIX ⚠️
|
|
32
|
+
* * Android's build system (Gradle) generates resource IDs based on filenames WITHOUT extensions.
|
|
33
|
+
* If we generate "game_go_v2.mp3" and "game_go_v2.json", Android sees them both
|
|
34
|
+
* as the resource ID `R.raw.game_go_v2`, causing a "Duplicate resources" build error.
|
|
35
|
+
* * To fix this, make a script to automatically rename the generated JSON file to:
|
|
36
|
+
* `${outputFileName}_data.json`
|
|
37
|
+
* * Result:
|
|
38
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
39
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
30
44
|
### Looping Sounds
|
|
31
45
|
|
|
32
46
|
You can create looping sounds by using the `--loop` option with the `audiosprite` command. The value of the `--loop` option should be the name of the sound you want to loop.
|
|
@@ -41,6 +55,40 @@ When you play a looping sound, it will play continuously until you stop it using
|
|
|
41
55
|
|
|
42
56
|
Then, you can use the `AudioSpritePlayer` to play the sounds from the sprite.
|
|
43
57
|
|
|
58
|
+
### Type Safety for Native Audio Extensions
|
|
59
|
+
|
|
60
|
+
This library includes robust type definitions for `react-native-audio-api` extensions, such as `createBufferQueueSource`. These types are automatically generated and synchronized with the native audio library version `0.10.1`.
|
|
61
|
+
|
|
62
|
+
### Audio Routing and Volume Control (Mixer Graph)
|
|
63
|
+
|
|
64
|
+
The library features a mixer graph that allows you to control the volume of Sound Effects (SFX) and Music separately, as well as a global Master volume.
|
|
65
|
+
|
|
66
|
+
- `sfx`: Short sound effects (coins, jumps, UI). High priority.
|
|
67
|
+
- `music`: Background tracks. Lower priority.
|
|
68
|
+
|
|
69
|
+
You can specify the channel when playing a sound:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Play on 'sfx' channel (default)
|
|
73
|
+
player.play('coin_sound');
|
|
74
|
+
|
|
75
|
+
// Play on 'music' channel
|
|
76
|
+
player.play('bg_music', { channel: 'music' });
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
You can control the volume dynamically:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Set Music Volume (0.0 to 1.0)
|
|
83
|
+
player.setMusicVolume(0.5);
|
|
84
|
+
|
|
85
|
+
// Set SFX Volume (0.0 to 1.0)
|
|
86
|
+
player.setSFXVolume(0.8);
|
|
87
|
+
|
|
88
|
+
// Set Master Volume (affects both)
|
|
89
|
+
player.volume = 1.0;
|
|
90
|
+
```
|
|
91
|
+
|
|
44
92
|
### Browser Environment
|
|
45
93
|
|
|
46
94
|
```typescript
|
|
@@ -159,7 +207,12 @@ export default function App() {
|
|
|
159
207
|
const playSound = (soundName: string) => {
|
|
160
208
|
const player = playerRef.current;
|
|
161
209
|
if (player && isLoaded) {
|
|
162
|
-
|
|
210
|
+
// Play on music channel
|
|
211
|
+
if (soundName === 'bg_loop') {
|
|
212
|
+
player.play(soundName, { channel: 'music' });
|
|
213
|
+
} else {
|
|
214
|
+
player.play(soundName);
|
|
215
|
+
}
|
|
163
216
|
console.log(`Playing sound: ${soundName}`);
|
|
164
217
|
} else {
|
|
165
218
|
console.warn('Player not loaded yet.');
|
|
@@ -263,6 +316,315 @@ Made with [create-react-native-library](https://github.com/callstack/react-nativ
|
|
|
263
316
|
|
|
264
317
|
# Translations
|
|
265
318
|
|
|
319
|
+
## Telugu
|
|
320
|
+
|
|
321
|
+

|
|
322
|
+
|
|
323
|
+
# react-native-audiosprites
|
|
324
|
+
|
|
325
|
+
'audiosprite' టూల్ ద్వారా రూపొందించబడిన ఆడియో స్ప్రైట్ల కోసం ఒక యూనివర్సల్ ప్లేయర్.
|
|
326
|
+
ఒకే సమయంలో అనేక శబ్దాలను ప్లే చేయడానికి మద్దతు ఇస్తుంది!
|
|
327
|
+
|
|
328
|
+
## ఇన్స్టాలేషన్
|
|
329
|
+
|
|
330
|
+
```sh
|
|
331
|
+
npm install react-native-audiosprites
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
```sh
|
|
335
|
+
yarn add react-native-audiosprites
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## వినియోగం
|
|
339
|
+
|
|
340
|
+
ముందుగా, మీరు `audiosprite` టూల్ను ఉపయోగించి ఆడియో స్ప్రైట్ మరియు JSON మానిఫెస్ట్ ఫైల్ను రూపొందించాలి.
|
|
341
|
+
|
|
342
|
+
మీరు [`audiosprite`](https://www.npmjs.com/package/audiosprite)ని గ్లోబల్గా ఇన్స్టాల్ చేశారని అనుకుందాం:
|
|
343
|
+
|
|
344
|
+
```sh
|
|
345
|
+
audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg_loop" src/__tests__/sounds/bg_loop.wav src/__tests__/sounds/Sound_1.m4a src/__tests__/sounds/Sound_2.m4a src/__tests__/sounds/Sound_3.m4a src/__tests__/sounds/Sound_4.m4a
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
ఈ కమాండ్ `src/__tests__/sounds/` డైరెక్టరీలో `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a`, మరియు `mygameaudio.ac3` ఫైళ్లను సృష్టిస్తుంది.
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* ⚠️ ANDROID వనరుల సంఘర్షణ పరిష్కారం ⚠️
|
|
352
|
+
* * Android బిల్డ్ సిస్టమ్ (Gradle) ఎక్స్టెన్షన్లు లేకుండా ఫైల్నేమ్ల ఆధారంగా వనరుల IDలను సృష్టిస్తుంది.
|
|
353
|
+
* ఒకవేళ మనం "game_go_v2.mp3" మరియు "game_go_v2.json"ను రూపొందిస్తే, Android రెండింటినీ
|
|
354
|
+
* `R.raw.game_go_v2` అనే ఒకే వనరు IDగా చూస్తుంది, దీనివల్ల "డూప్లికేట్ వనరులు" బిల్డ్ ఎర్రర్ వస్తుంది.
|
|
355
|
+
* * దీన్ని పరిష్కరించడానికి, రూపొందించిన JSON ఫైల్ పేరును ఈ విధంగా మార్చాలి:
|
|
356
|
+
* `${outputFileName}_data.json`
|
|
357
|
+
* * ఫలితం:
|
|
358
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
359
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
360
|
+
*/
|
|
361
|
+
|
|
362
|
+
### లూపింగ్ సౌండ్స్ (Looping Sounds)
|
|
363
|
+
|
|
364
|
+
మీరు `audiosprite` కమాండ్తో `--loop` ఎంపికను ఉపయోగించి లూపింగ్ శబ్దాలను సృష్టించవచ్చు. `--loop` ఎంపిక యొక్క విలువ మీరు లూప్ చేయాలనుకుంటున్న శబ్దం పేరు అయి ఉండాలి.
|
|
365
|
+
|
|
366
|
+
ఉదాహరణకు, `bg_music` శబ్దాన్ని లూప్ చేయడానికి, మీరు ఈ కింది కమాండ్ను ఉపయోగిస్తారు:
|
|
367
|
+
|
|
368
|
+
```sh
|
|
369
|
+
audiosprite --output audiosprite --format howler --loop "bg_music" --path ./src/__tests__/ Sound_1.m4a Sound_2.m4a Sound_3.m4a Sound_4.m4a bg_music.wav
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
మీరు లూపింగ్ శబ్దాన్ని ప్లే చేసినప్పుడు, మీరు `player.stop()` పద్ధతిని ఉపయోగించి దాన్ని ఆపే వరకు అది నిరంతరాయంగా ప్లే అవుతూనే ఉంటుంది. వెబ్ మరియు మొబైల్ ప్లాట్ఫారమ్లలో లూపింగ్ ఫంక్షనాలిటీకి మద్దతు ఉంది.
|
|
373
|
+
|
|
374
|
+
తరువాత, మీరు స్ప్రైట్ నుండి శబ్దాలను ప్లే చేయడానికి `AudioSpritePlayer`ని ఉపయోగించవచ్చు.
|
|
375
|
+
|
|
376
|
+
### ఆడియో రూటింగ్ మరియు వాల్యూమ్ నియంత్రణ (మిక్సర్ గ్రాఫ్)
|
|
377
|
+
|
|
378
|
+
ఈ లైబ్రరీ మిక్సర్ గ్రాఫ్ ఫీచర్ను కలిగి ఉంది, ఇది సౌండ్ ఎఫెక్ట్స్ (SFX) మరియు మ్యూజిక్ వాల్యూమ్లను విడివిడిగా, అలాగే గ్లోబల్ మాస్టర్ వాల్యూమ్ను నియంత్రించడానికి మిమ్మల్ని అనుమతిస్తుంది.
|
|
379
|
+
|
|
380
|
+
- `sfx`: చిన్న సౌండ్ ఎఫెక్ట్స్ (కాయిన్స్, జంప్స్, UI). అధిక ప్రాధాన్యత.
|
|
381
|
+
- `music`: నేపథ్య ట్రాక్లు (Background tracks). తక్కువ ప్రాధాన్యత.
|
|
382
|
+
|
|
383
|
+
శబ్దాన్ని ప్లే చేస్తున్నప్పుడు మీరు ఛానెల్ని పేర్కొనవచ్చు:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
// 'sfx' ఛానెల్లో ప్లే చేయండి (డిఫాల్ట్)
|
|
387
|
+
player.play('coin_sound');
|
|
388
|
+
|
|
389
|
+
// 'music' ఛానెల్లో ప్లే చేయండి
|
|
390
|
+
player.play('bg_music', { channel: 'music' });
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
మీరు వాల్యూమ్ను డైనమిక్గా నియంత్రించవచ్చు:
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// మ్యూజిక్ వాల్యూమ్ను సెట్ చేయండి (0.0 నుండి 1.0)
|
|
397
|
+
player.setMusicVolume(0.5);
|
|
398
|
+
|
|
399
|
+
// SFX వాల్యూమ్ను సెట్ చేయండి (0.0 నుండి 1.0)
|
|
400
|
+
player.setSFXVolume(0.8);
|
|
401
|
+
|
|
402
|
+
// మాస్టర్ వాల్యూమ్ను సెట్ చేయండి (రెండింటినీ ప్రభావితం చేస్తుంది)
|
|
403
|
+
player.volume = 1.0;
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### బ్రౌజర్ ఎన్విరాన్మెంట్ (Browser Environment)
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
import { AudioSpritePlayer } from 'react-native-audiosprites';
|
|
410
|
+
|
|
411
|
+
const player = new AudioSpritePlayer({
|
|
412
|
+
platform: 'web',
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
async function playSound(soundName: string) {
|
|
416
|
+
try {
|
|
417
|
+
// ఆడియో స్ప్రైట్ మానిఫెస్ట్ మరియు ఆడియో ఫైళ్లను లోడ్ చేయండి
|
|
418
|
+
// మీ audiosprite.json ఫైల్ పాత్ను సరిచూసుకోండి
|
|
419
|
+
await player.load('./src/__tests__/sounds/mygameaudio.json');
|
|
420
|
+
console.log('ఆడియో స్ప్రైట్ విజయవంతంగా లోడ్ అయింది.');
|
|
421
|
+
|
|
422
|
+
// స్ప్రైట్మ్యాప్ నుండి శబ్దాన్ని ప్లే చేయండి
|
|
423
|
+
player.play(soundName);
|
|
424
|
+
console.log(`శబ్దాన్ని ప్లే చేస్తోంది: ${soundName}`);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
console.error('శబ్దాన్ని ప్లే చేయడంలో లోపం:', error);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function stopSound() {
|
|
431
|
+
player.stop();
|
|
432
|
+
console.log('లూపింగ్ శబ్దం ఆగిపోయింది.');
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// వినియోగ ఉదాహరణ:
|
|
436
|
+
playSound('Sound_1');
|
|
437
|
+
// playSound('Sound_2');
|
|
438
|
+
// లూపింగ్ శబ్దాన్ని ఆపడానికి:
|
|
439
|
+
// stopSound();
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### రియాక్ట్ నేటివ్ ఎన్విరాన్మెంట్ (React Native Environment)
|
|
443
|
+
|
|
444
|
+
రియాక్ట్ నేటివ్ కోసం, ఆడియో ప్లేబ్యాక్ మరియు అసెట్ లోడింగ్ను నిర్వహించడానికి మీకు `react-native-audio-api` మరియు `expo-asset` అవసరం.
|
|
445
|
+
|
|
446
|
+
ముందుగా, డిపెండెన్సీలను ఇన్స్టాల్ చేయండి:
|
|
447
|
+
|
|
448
|
+
```sh
|
|
449
|
+
npm install react-native-audio-api expo-asset expo-file-system
|
|
450
|
+
# లేదా
|
|
451
|
+
yarn add react-native-audio-api expo-asset expo-file-system
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`react-native-audio-api` డాక్యుమెంటేషన్ ప్రకారం `metro.config.js`ని మార్చండి: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started
|
|
455
|
+
|
|
456
|
+
```js
|
|
457
|
+
module.exports = wrapWithAudioAPIMetroConfig(config);
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
తరువాత, మీరు దీన్ని మీ కాంపోనెంట్లో ఉపయోగించవచ్చు:
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
import { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';
|
|
464
|
+
import { AudioSpritePlayer } from 'react-native-audiosprites';
|
|
465
|
+
import { AudioManager, AudioContext } from 'react-native-audio-api';
|
|
466
|
+
import { useEffect, useState, useRef } from 'react';
|
|
467
|
+
import { Asset } from 'expo-asset';
|
|
468
|
+
import { fetch } from 'expo/fetch';
|
|
469
|
+
import manifest from '../assets/mygameaudio.json';
|
|
470
|
+
|
|
471
|
+
// ఆడియో అసెట్ను ఇంపోర్ట్ చేయండి
|
|
472
|
+
const audioAsset = require('../assets/mygameaudio.mp3');
|
|
473
|
+
|
|
474
|
+
export default function App() {
|
|
475
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
476
|
+
const playerRef = useRef<AudioSpritePlayer | null>(null);
|
|
477
|
+
|
|
478
|
+
useEffect(() => {
|
|
479
|
+
const loadPlayer = async () => {
|
|
480
|
+
const asset = Asset.fromModule(audioAsset);
|
|
481
|
+
await asset.downloadAsync();
|
|
482
|
+
const audioUri = asset.localUri || asset.uri;
|
|
483
|
+
|
|
484
|
+
if (!audioUri) {
|
|
485
|
+
console.error('ఆడియో URIని పొందడంలో విఫలమైంది.');
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (Platform.OS === 'ios') {
|
|
490
|
+
try {
|
|
491
|
+
await AudioManager.setAudioSessionOptions({
|
|
492
|
+
iosCategory: 'playback',
|
|
493
|
+
iosOptions: ['mixWithOthers'],
|
|
494
|
+
});
|
|
495
|
+
await AudioManager.setAudioSessionActivity(true);
|
|
496
|
+
} catch (e) {
|
|
497
|
+
console.error('AudioSession ఎంపికలను కాన్ఫిగర్ చేయడంలో విఫలమైంది:', e);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const audioContext = new AudioContext();
|
|
502
|
+
const audioPlayer = new AudioSpritePlayer({
|
|
503
|
+
audioContext,
|
|
504
|
+
fetch: fetch.bind(globalThis),
|
|
505
|
+
platform: Platform.OS,
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
try {
|
|
509
|
+
await audioPlayer.load(manifest, audioUri);
|
|
510
|
+
playerRef.current = audioPlayer;
|
|
511
|
+
setIsLoaded(true);
|
|
512
|
+
console.log('ఆడియో స్ప్రైట్ విజయవంతంగా లోడ్ అయింది.');
|
|
513
|
+
} catch (error) {
|
|
514
|
+
console.error('ఆడియో స్ప్రైట్ను లోడ్ చేయడంలో విఫలమైంది:', error);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
loadPlayer();
|
|
519
|
+
}, []);
|
|
520
|
+
|
|
521
|
+
const playSound = (soundName: string) => {
|
|
522
|
+
const player = playerRef.current;
|
|
523
|
+
if (player && isLoaded) {
|
|
524
|
+
if (soundName === 'bg_loop') {
|
|
525
|
+
player.play(soundName, { channel: 'music' });
|
|
526
|
+
} else {
|
|
527
|
+
player.play(soundName);
|
|
528
|
+
}
|
|
529
|
+
console.log(`శబ్దాన్ని ప్లే చేస్తోంది: ${soundName}`);
|
|
530
|
+
} else {
|
|
531
|
+
console.warn('ప్లేయర్ ఇంకా లోడ్ కాలేదు.');
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
const stopBGM = () => {
|
|
536
|
+
const player = playerRef.current;
|
|
537
|
+
if (player) {
|
|
538
|
+
player.stop();
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
return (
|
|
543
|
+
<View style={styles.container}>
|
|
544
|
+
<Text>AudioSprite Player ఉదాహరణ</Text>
|
|
545
|
+
<TouchableOpacity
|
|
546
|
+
onPress={() => loadPlayer()}
|
|
547
|
+
style={styles.button}
|
|
548
|
+
disabled={!isLoaded}
|
|
549
|
+
>
|
|
550
|
+
<Text style={styles.buttonText}>ప్లేయర్ని లోడ్ చేయండి</Text>
|
|
551
|
+
</TouchableOpacity>
|
|
552
|
+
<TouchableOpacity
|
|
553
|
+
onPress={() => playSound('Sound_1')}
|
|
554
|
+
style={styles.button}
|
|
555
|
+
disabled={!isLoaded}
|
|
556
|
+
>
|
|
557
|
+
<Text style={styles.buttonText}>Sound 1 ప్లే చేయండి</Text>
|
|
558
|
+
</TouchableOpacity>
|
|
559
|
+
<TouchableOpacity
|
|
560
|
+
onPress={() => playSound('Sound_2')}
|
|
561
|
+
style={styles.button}
|
|
562
|
+
disabled={!isLoaded}
|
|
563
|
+
>
|
|
564
|
+
<Text style={styles.buttonText}>Sound 2 ప్లే చేయండి</Text>
|
|
565
|
+
</TouchableOpacity>
|
|
566
|
+
<TouchableOpacity
|
|
567
|
+
onPress={() => playSound('bg_loop')}
|
|
568
|
+
style={styles.button}
|
|
569
|
+
disabled={!isLoaded}
|
|
570
|
+
>
|
|
571
|
+
<Text style={styles.buttonText}>బ్యాక్గ్రౌండ్ లూప్ను ప్లే చేయండి</Text>
|
|
572
|
+
</TouchableOpacity>
|
|
573
|
+
<TouchableOpacity
|
|
574
|
+
onPress={stopBGM}
|
|
575
|
+
style={styles.button}
|
|
576
|
+
disabled={!isLoaded}
|
|
577
|
+
>
|
|
578
|
+
<Text style={styles.buttonText}>BGM ఆపు</Text>
|
|
579
|
+
</TouchableOpacity>
|
|
580
|
+
</View>
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
const styles = StyleSheet.create({
|
|
585
|
+
container: {
|
|
586
|
+
flex: 1,
|
|
587
|
+
alignItems: 'center',
|
|
588
|
+
justifyContent: 'center',
|
|
589
|
+
},
|
|
590
|
+
button: {
|
|
591
|
+
backgroundColor: '#DDDDDD',
|
|
592
|
+
padding: 10,
|
|
593
|
+
marginVertical: 5,
|
|
594
|
+
borderRadius: 5,
|
|
595
|
+
},
|
|
596
|
+
buttonText: {
|
|
597
|
+
color: '#000000',
|
|
598
|
+
textAlign: 'center',
|
|
599
|
+
},
|
|
600
|
+
});
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## స్ఫూర్తి (Inspiration)
|
|
604
|
+
|
|
605
|
+
https://github.com/goldfire/howler.js
|
|
606
|
+
జనరేట్ చేయబడిన json new Howl({
|
|
607
|
+
sprite: {
|
|
608
|
+
key1: [offset, duration, (loop)]
|
|
609
|
+
},
|
|
610
|
+
}); తో కూడా పనిచేస్తుంది.
|
|
611
|
+
|
|
612
|
+
## సహకారం (Contributing)
|
|
613
|
+
|
|
614
|
+
- [డెవలప్మెంట్ వర్క్ఫ్లో](CONTRIBUTING.md#development-workflow)
|
|
615
|
+
- [పుల్ రిక్వెస్ట్ పంపడం](CONTRIBUTING.md#sending-a-pull-request)
|
|
616
|
+
- [ప్రవర్తనా నియమావళి](CODE_OF_CONDUCT.md)
|
|
617
|
+
|
|
618
|
+
## లైసెన్స్ (License)
|
|
619
|
+
|
|
620
|
+
MIT
|
|
621
|
+
|
|
622
|
+
## క్రెడిట్స్ (Credits)
|
|
623
|
+
|
|
624
|
+
[Shaker, Woda, Conga, Bongo, Templeblock.wav](https://freesound.org/people/kwazi/sounds/34115/) by [kwazi](https://freesound.org/people/kwazi/) | లైసెన్స్: [అట్రిబ్యూషన్ 3.0](http://creativecommons.org/licenses/by/3.0/)
|
|
625
|
+
|
|
626
|
+
[create-react-native-library](https://github.com/callstack/react-native-builder-bob)తో తయారు చేయబడింది
|
|
627
|
+
|
|
266
628
|
## Spanish
|
|
267
629
|
|
|
268
630
|

|
|
@@ -294,6 +656,18 @@ audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg
|
|
|
294
656
|
|
|
295
657
|
Este comando generará `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a` y `mygameaudio.ac3` en el directorio `src/__tests__/sounds/`.
|
|
296
658
|
|
|
659
|
+
/**
|
|
660
|
+
* ⚠️ SOLUCIÓN DE CONFLICTO DE RECURSOS DE ANDROID ⚠️
|
|
661
|
+
* * El sistema de compilación de Android (Gradle) genera ID de recursos basados en nombres de archivo SIN extensiones.
|
|
662
|
+
* Si generamos "game_go_v2.mp3" y "game_go_v2.json", Android los ve a ambos
|
|
663
|
+
* como el ID de recurso `R.raw.game_go_v2`, lo que causa un error de compilación de "Recursos duplicados".
|
|
664
|
+
* * Para solucionar esto, renombre el archivo JSON generado a:
|
|
665
|
+
* `${outputFileName}_data.json`
|
|
666
|
+
* * Resultado:
|
|
667
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
668
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
669
|
+
*/
|
|
670
|
+
|
|
297
671
|
### Sonidos en Bucle
|
|
298
672
|
|
|
299
673
|
Puedes crear sonidos en bucle usando la opción `--loop` con el comando `audiosprite`. El valor de la opción `--loop` debe ser el nombre del sonido que deseas repetir.
|
|
@@ -426,7 +800,11 @@ export default function App() {
|
|
|
426
800
|
const playSound = (soundName: string) => {
|
|
427
801
|
const player = playerRef.current;
|
|
428
802
|
if (player && isLoaded) {
|
|
429
|
-
|
|
803
|
+
if (soundName === 'bg_loop') {
|
|
804
|
+
player.play(soundName, { channel: 'music' });
|
|
805
|
+
} else {
|
|
806
|
+
player.play(soundName);
|
|
807
|
+
}
|
|
430
808
|
console.log(`Reproduciendo sonido: ${soundName}`);
|
|
431
809
|
} else {
|
|
432
810
|
console.warn('El reproductor aún no se ha cargado.');
|
|
@@ -557,6 +935,18 @@ audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg
|
|
|
557
935
|
|
|
558
936
|
Эта команда создаст `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a` и `mygameaudio.ac3` в каталоге `src/__tests__/sounds/`.
|
|
559
937
|
|
|
938
|
+
/**
|
|
939
|
+
* ⚠️ ИСПРАВЛЕНИЕ КОНФЛИКТА РЕСУРСОВ ANDROID ⚠️
|
|
940
|
+
* * Система сборки Android (Gradle) генерирует идентификаторы ресурсов на основе имен файлов БЕЗ расширений.
|
|
941
|
+
* Если мы сгенерируем "game_go_v2.mp3" и "game_go_v2.json", Android увидит их обоих
|
|
942
|
+
* как идентификатор ресурса `R.raw.game_go_v2`, что вызовет ошибку сборки "Дублирующиеся ресурсы".
|
|
943
|
+
* * Чтобы исправить это, переименуйте сгенерированный файл JSON в:
|
|
944
|
+
* `${outputFileName}_data.json`
|
|
945
|
+
* * Результат:
|
|
946
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
947
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
948
|
+
*/
|
|
949
|
+
|
|
560
950
|
### Зацикленные звуки
|
|
561
951
|
|
|
562
952
|
Вы можете создавать зацикленные звуки, используя опцию `--loop` с командой `audiosprite`. Значением опции `--loop` должно быть имя звука, который вы хотите зациклить.
|
|
@@ -689,7 +1079,11 @@ export default function App() {
|
|
|
689
1079
|
const playSound = (soundName: string) => {
|
|
690
1080
|
const player = playerRef.current;
|
|
691
1081
|
if (player && isLoaded) {
|
|
692
|
-
|
|
1082
|
+
if (soundName === 'bg_loop') {
|
|
1083
|
+
player.play(soundName, { channel: 'music' });
|
|
1084
|
+
} else {
|
|
1085
|
+
player.play(soundName);
|
|
1086
|
+
}
|
|
693
1087
|
console.log(`Воспроизведение звука: ${soundName}`);
|
|
694
1088
|
} else {
|
|
695
1089
|
console.warn('Проигрыватель еще не загружен.');
|
|
@@ -820,6 +1214,18 @@ audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg
|
|
|
820
1214
|
|
|
821
1215
|
यह कमांड `src/__tests__/sounds/` डायरेक्टरी में `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a`, और `mygameaudio.ac3` उत्पन्न करेगा।
|
|
822
1216
|
|
|
1217
|
+
/**
|
|
1218
|
+
* ⚠️ Android संसाधन संघर्ष सुधार ⚠️
|
|
1219
|
+
* * Android की बिल्ड सिस्टम (Gradle) फ़ाइल नामों के आधार पर संसाधन ID उत्पन्न करती है बिना एक्सटेंशन के।
|
|
1220
|
+
* यदि हम "game_go_v2.mp3" और "game_go_v2.json" उत्पन्न करते हैं, तो Android उन दोनों को
|
|
1221
|
+
* `R.raw.game_go_v2` संसाधन ID के रूप में देखता है, जिससे "डुप्लिकेट संसाधन" बिल्ड त्रुटि होती है।
|
|
1222
|
+
* * इसे ठीक करने के लिए, उत्पन्न JSON फ़ाइल का नाम बदलकर यह करें:
|
|
1223
|
+
* `${outputFileName}_data.json`
|
|
1224
|
+
* * परिणाम:
|
|
1225
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
1226
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
1227
|
+
*/
|
|
1228
|
+
|
|
823
1229
|
### लूपिंग ध्वनियाँ
|
|
824
1230
|
|
|
825
1231
|
आप `audiosprite` कमांड के साथ `--loop` विकल्प का उपयोग करके लूपिंग ध्वनियाँ बना सकते हैं। `--loop` विकल्प का मान उस ध्वनि का नाम होना चाहिए जिसे आप लूप करना चाहते हैं।
|
|
@@ -952,7 +1358,11 @@ export default function App() {
|
|
|
952
1358
|
const playSound = (soundName: string) => {
|
|
953
1359
|
const player = playerRef.current;
|
|
954
1360
|
if (player && isLoaded) {
|
|
955
|
-
|
|
1361
|
+
if (soundName === 'bg_loop') {
|
|
1362
|
+
player.play(soundName, { channel: 'music' });
|
|
1363
|
+
} else {
|
|
1364
|
+
player.play(soundName);
|
|
1365
|
+
}
|
|
956
1366
|
console.log(`ध्वनि बज रही है: ${soundName}`);
|
|
957
1367
|
} else {
|
|
958
1368
|
console.warn('खिलाड़ी अभी तक लोड नहीं हुआ है।');
|
|
@@ -1083,6 +1493,18 @@ audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg
|
|
|
1083
1493
|
|
|
1084
1494
|
此命令将在 `src/__tests__/sounds/` 目录中生成 `mygameaudio.json`、`mygameaudio.mp3`、`mygameaudio.ogg`、`mygameaudio.m4a` 和 `mygameaudio.ac3`。
|
|
1085
1495
|
|
|
1496
|
+
/**
|
|
1497
|
+
* ⚠️ ANDROID 资源冲突修复 ⚠️
|
|
1498
|
+
* * Android 的构建系统 (Gradle) 基于不带扩展名的文件名生成资源 ID。
|
|
1499
|
+
* 如果我们生成 "game_go_v2.mp3" 和 "game_go_v2.json",Android 会将它们都视为
|
|
1500
|
+
* 资源 ID `R.raw.game_go_v2`,从而导致“重复资源”构建错误。
|
|
1501
|
+
* * 要修复此问题,请将生成的 JSON 文件重命名为:
|
|
1502
|
+
* `${outputFileName}_data.json`
|
|
1503
|
+
* * 结果:
|
|
1504
|
+
* - game_go_v2.mp3 -> R.raw.game_go_v2
|
|
1505
|
+
* - game_go_v2_data.json -> R.raw.game_go_v2_data
|
|
1506
|
+
*/
|
|
1507
|
+
|
|
1086
1508
|
### 循环声音
|
|
1087
1509
|
|
|
1088
1510
|
您可以使用 `audiosprite` 命令的 `--loop` 选项创建循环声音。`--loop` 选项的值应该是您想要循环的声音的名称。
|
|
@@ -1215,7 +1637,11 @@ export default function App() {
|
|
|
1215
1637
|
const playSound = (soundName: string) => {
|
|
1216
1638
|
const player = playerRef.current;
|
|
1217
1639
|
if (player && isLoaded) {
|
|
1218
|
-
|
|
1640
|
+
if (soundName === 'bg_loop') {
|
|
1641
|
+
player.play(soundName, { channel: 'music' });
|
|
1642
|
+
} else {
|
|
1643
|
+
player.play(soundName);
|
|
1644
|
+
}
|
|
1219
1645
|
console.log(`正在播放声音: ${soundName}`);
|
|
1220
1646
|
} else {
|
|
1221
1647
|
console.warn('播放器尚未加载。');
|
|
@@ -1313,4 +1739,4 @@ key1: [offset, duration, (loop)]
|
|
|
1313
1739
|
|
|
1314
1740
|
[Shaker, Woda, Conga, Bongo, Templeblock.wav](https://freesound.org/people/kwazi/sounds/34115/) by [kwazi](https://freesound.org/people/kwazi/) | 执照: [署名 3.0](http://creativecommons.org/licenses/by/3.0/)
|
|
1315
1741
|
|
|
1316
|
-
使用 [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 制作
|
|
1742
|
+
使用 [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 制作
|
package/lib/module/index.js
CHANGED
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
* Requires an AudioContext and fetch to be injected.
|
|
6
6
|
* Uses AudioBufferQueueSourceNode and buffer splitting for mobile stability.
|
|
7
7
|
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Defines the available audio routing channels.
|
|
11
|
+
* - 'sfx': Short sound effects (coins, jumps, UI). High priority, usually usually non-looping.
|
|
12
|
+
* - 'music': Background tracks. Lower priority, usually looping, separate volume control.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for playing a specific sound sprite.
|
|
17
|
+
*/
|
|
18
|
+
|
|
8
19
|
export class AudioSpritePlayer {
|
|
9
20
|
// The full audio buffer
|
|
10
21
|
|
|
@@ -14,6 +25,8 @@ export class AudioSpritePlayer {
|
|
|
14
25
|
sourcePool = []; // NEW: Pool for non-looping sources
|
|
15
26
|
maxPoolSize = 5; // Adjust this based on testing (5 is a good start)
|
|
16
27
|
|
|
28
|
+
// NEW: The Mixer
|
|
29
|
+
|
|
17
30
|
constructor({
|
|
18
31
|
audioContext,
|
|
19
32
|
fetch,
|
|
@@ -43,6 +56,20 @@ export class AudioSpritePlayer {
|
|
|
43
56
|
// @ts-ignore
|
|
44
57
|
this.audioContext = new AudioContext();
|
|
45
58
|
}
|
|
59
|
+
|
|
60
|
+
// 1. Create Master Output
|
|
61
|
+
this.masterGain = this.audioContext.createGain();
|
|
62
|
+
this.masterGain.gain.value = 1.0;
|
|
63
|
+
this.masterGain.connect(this.audioContext.destination);
|
|
64
|
+
|
|
65
|
+
// 2. Create Channels
|
|
66
|
+
this.sfxGain = this.audioContext.createGain();
|
|
67
|
+
this.sfxGain.gain.value = 1.0;
|
|
68
|
+
this.sfxGain.connect(this.masterGain); // Connect to Master
|
|
69
|
+
|
|
70
|
+
this.musicGain = this.audioContext.createGain();
|
|
71
|
+
this.musicGain.gain.value = 1.0;
|
|
72
|
+
this.musicGain.connect(this.masterGain); // Connect to Master
|
|
46
73
|
}
|
|
47
74
|
|
|
48
75
|
/**
|
|
@@ -111,7 +138,7 @@ export class AudioSpritePlayer {
|
|
|
111
138
|
if (this.platform === 'web') {
|
|
112
139
|
// Web logic remains simple: always create a standard AudioBufferSourceNode
|
|
113
140
|
const source = this.audioContext.createBufferSource();
|
|
114
|
-
source.connect(this.audioContext.destination);
|
|
141
|
+
// source.connect(this.audioContext.destination);
|
|
115
142
|
return source;
|
|
116
143
|
}
|
|
117
144
|
|
|
@@ -129,7 +156,7 @@ export class AudioSpritePlayer {
|
|
|
129
156
|
return null;
|
|
130
157
|
}
|
|
131
158
|
source = this.audioContext.createBufferQueueSource();
|
|
132
|
-
source.connect(this.audioContext.destination);
|
|
159
|
+
// source.connect(this.audioContext.destination);
|
|
133
160
|
// console.log('Created new source. Pool size:', this.sourcePool.length);
|
|
134
161
|
} else {
|
|
135
162
|
// If pool is full, we might have to block or fail.
|
|
@@ -213,7 +240,7 @@ export class AudioSpritePlayer {
|
|
|
213
240
|
throw error; // Re-throw for user to catch
|
|
214
241
|
}
|
|
215
242
|
}
|
|
216
|
-
play(soundName) {
|
|
243
|
+
play(soundName, options) {
|
|
217
244
|
if (!this.audioBuffer || !this.manifest) {
|
|
218
245
|
console.warn('Audio sprite not loaded. Call load() first.');
|
|
219
246
|
return;
|
|
@@ -235,6 +262,15 @@ export class AudioSpritePlayer {
|
|
|
235
262
|
console.warn(`Sound "${soundName}" has invalid duration.`);
|
|
236
263
|
return;
|
|
237
264
|
}
|
|
265
|
+
|
|
266
|
+
// 1. Determine Channel (Default to 'sfx')
|
|
267
|
+
const channel = options?.channel || 'sfx';
|
|
268
|
+
const targetNode = channel === 'music' ? this.musicGain : this.sfxGain;
|
|
269
|
+
|
|
270
|
+
// 2. Determine Loop (Options override Manifest)
|
|
271
|
+
// defined in your existing code as: const sound = this.manifest.sprite[soundName];
|
|
272
|
+
// const manifestLoop = sound[2];
|
|
273
|
+
const loop = options?.loop !== undefined ? options.loop : sound[2];
|
|
238
274
|
let source;
|
|
239
275
|
const spriteBuffer = this.spriteBufferCache[soundName];
|
|
240
276
|
|
|
@@ -248,12 +284,12 @@ export class AudioSpritePlayer {
|
|
|
248
284
|
console.error('RNAS Error: createBufferQueueSource is not available on this native platform.');
|
|
249
285
|
return;
|
|
250
286
|
}
|
|
251
|
-
const loop = sound[2];
|
|
252
287
|
if (loop) {
|
|
253
288
|
// Always use AudioBufferQueueSourceNode
|
|
254
289
|
source = this.audioContext.createBufferQueueSource();
|
|
255
290
|
source.enqueueBuffer(spriteBuffer);
|
|
256
|
-
source.connect(this.audioContext.destination);
|
|
291
|
+
// source.connect(this.audioContext.destination);
|
|
292
|
+
source.connect(targetNode);
|
|
257
293
|
|
|
258
294
|
// Manual looping using onEnded
|
|
259
295
|
const loopHandler = () => {
|
|
@@ -277,6 +313,10 @@ export class AudioSpritePlayer {
|
|
|
277
313
|
source = this._getOrCreateSourceNode();
|
|
278
314
|
if (!source) return; // Dropped sound because pool was full
|
|
279
315
|
|
|
316
|
+
// Reconnect to the correct channel (since pooled nodes might have been connected elsewhere)
|
|
317
|
+
source.disconnect();
|
|
318
|
+
source.connect(targetNode);
|
|
319
|
+
|
|
280
320
|
// Must re-enqueue the buffer since the source was reused
|
|
281
321
|
source.enqueueBuffer(spriteBuffer);
|
|
282
322
|
|
|
@@ -291,8 +331,10 @@ export class AudioSpritePlayer {
|
|
|
291
331
|
return;
|
|
292
332
|
}
|
|
293
333
|
source.buffer = spriteBuffer;
|
|
294
|
-
source.connect(this.audioContext.destination);
|
|
295
|
-
|
|
334
|
+
// source.connect(this.audioContext.destination);
|
|
335
|
+
source.connect(targetNode);
|
|
336
|
+
|
|
337
|
+
// const loop = sound[2]; // audiosprite stores loop as the third element in the array
|
|
296
338
|
if (loop) {
|
|
297
339
|
source.loop = true;
|
|
298
340
|
source.loopStart = 0; // Relative to the spriteBuffer
|
|
@@ -336,5 +378,41 @@ export class AudioSpritePlayer {
|
|
|
336
378
|
console.log('RNAS: No looping audio to stop.');
|
|
337
379
|
}
|
|
338
380
|
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Sets the volume for background music only.
|
|
384
|
+
* @param value 0.0 to 1.0
|
|
385
|
+
*/
|
|
386
|
+
setMusicVolume(value) {
|
|
387
|
+
if (this.musicGain) {
|
|
388
|
+
// secure against uninitialized context
|
|
389
|
+
this.musicGain.gain.setTargetAtTime(value, this.audioContext.currentTime, 0.02);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Sets the volume for sound effects only.
|
|
395
|
+
* @param value 0.0 to 1.0
|
|
396
|
+
*/
|
|
397
|
+
setSFXVolume(value) {
|
|
398
|
+
if (this.sfxGain) {
|
|
399
|
+
this.sfxGain.gain.setTargetAtTime(value, this.audioContext.currentTime, 0.02);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Sets the Global Master Volume (affects both Music and SFX).
|
|
405
|
+
* @param value 0.0 to 1.0
|
|
406
|
+
*/
|
|
407
|
+
set volume(value) {
|
|
408
|
+
if (this.masterGain) {
|
|
409
|
+
this.masterGain.gain.setTargetAtTime(value, this.audioContext.currentTime, 0.02);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Master Volume getter
|
|
414
|
+
get volume() {
|
|
415
|
+
return this.masterGain?.gain?.value ?? 1.0;
|
|
416
|
+
}
|
|
339
417
|
}
|
|
340
418
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["AudioSpritePlayer","spriteBufferCache","loopingSource","sourcePool","maxPoolSize","constructor","audioContext","fetch","platform","AudioContext","Error","audioBuffer","manifest","createBufferSource","name","console","log","_cacheSpriteBuffers","sampleRate","numChannels","numberOfChannels","soundName","sprite","sound","startFrame","Math","floor","endFrame","ceil","durationFrames","warn","spriteBuffer","createBuffer","i","sourceData","getChannelData","destinationData","segment","subarray","set","_getOrCreateSourceNode","source","connect","destination","length","pop","onEnded","createBufferQueueSource","error","cleanupAndRecycle","push","disconnect","load","json","audio","decodedBuffer","response","ok","statusText","urls","audioFileName","audioUrl","URL","url","href","audioResponse","arrayBuffer","decodeAudioData","typedArrayView","Uint8Array","buffer","play","state","resume","catch","e","duration","loop","enqueueBuffer","loopHandler","start","stop","loopStart","loopEnd","getManifest","getAudioBuffer"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["AudioSpritePlayer","spriteBufferCache","loopingSource","sourcePool","maxPoolSize","constructor","audioContext","fetch","platform","AudioContext","Error","audioBuffer","manifest","createBufferSource","name","console","log","masterGain","createGain","gain","value","connect","destination","sfxGain","musicGain","_cacheSpriteBuffers","sampleRate","numChannels","numberOfChannels","soundName","sprite","sound","startFrame","Math","floor","endFrame","ceil","durationFrames","warn","spriteBuffer","createBuffer","i","sourceData","getChannelData","destinationData","segment","subarray","set","_getOrCreateSourceNode","source","length","pop","onEnded","createBufferQueueSource","error","cleanupAndRecycle","push","disconnect","load","json","audio","decodedBuffer","response","ok","statusText","urls","audioFileName","audioUrl","URL","url","href","audioResponse","arrayBuffer","decodeAudioData","typedArrayView","Uint8Array","buffer","play","options","state","resume","catch","e","duration","channel","targetNode","loop","undefined","enqueueBuffer","loopHandler","start","stop","loopStart","loopEnd","getManifest","getAudioBuffer","setMusicVolume","setTargetAtTime","currentTime","setSFXVolume","volume"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
* Requires an AudioContext and fetch to be injected.
|
|
4
4
|
* Uses AudioBufferQueueSourceNode and buffer splitting for mobile stability.
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Defines the available audio routing channels.
|
|
8
|
+
* - 'sfx': Short sound effects (coins, jumps, UI). High priority, usually usually non-looping.
|
|
9
|
+
* - 'music': Background tracks. Lower priority, usually looping, separate volume control.
|
|
10
|
+
*/
|
|
11
|
+
export type AudioChannel = 'sfx' | 'music';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for playing a specific sound sprite.
|
|
14
|
+
*/
|
|
15
|
+
export interface PlayOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Specifies which mixer channel to route the audio through.
|
|
18
|
+
* Use 'music' for BGM to ensure it responds to music volume settings.
|
|
19
|
+
* @default 'sfx'
|
|
20
|
+
*/
|
|
21
|
+
channel?: AudioChannel;
|
|
22
|
+
/**
|
|
23
|
+
* Force the sound to loop (or not), overriding the setting
|
|
24
|
+
* defined in the original audiosprite JSON manifest.
|
|
25
|
+
*/
|
|
26
|
+
loop?: boolean;
|
|
27
|
+
}
|
|
6
28
|
export declare class AudioSpritePlayer {
|
|
7
29
|
audioContext: any | null;
|
|
8
30
|
fetch: any | null;
|
|
@@ -13,6 +35,9 @@ export declare class AudioSpritePlayer {
|
|
|
13
35
|
private loopingSource;
|
|
14
36
|
private sourcePool;
|
|
15
37
|
private maxPoolSize;
|
|
38
|
+
masterGain: any;
|
|
39
|
+
sfxGain: any;
|
|
40
|
+
musicGain: any;
|
|
16
41
|
constructor({ audioContext, fetch, platform, }: {
|
|
17
42
|
audioContext: any | null;
|
|
18
43
|
fetch: any;
|
|
@@ -47,7 +72,7 @@ export declare class AudioSpritePlayer {
|
|
|
47
72
|
*/
|
|
48
73
|
private _getOrCreateSourceNode;
|
|
49
74
|
load(json: any, audio?: any): Promise<void>;
|
|
50
|
-
play(soundName: string): void;
|
|
75
|
+
play(soundName: string, options?: PlayOptions): void;
|
|
51
76
|
getManifest(): any;
|
|
52
77
|
getAudioBuffer(): any;
|
|
53
78
|
/**
|
|
@@ -55,5 +80,21 @@ export declare class AudioSpritePlayer {
|
|
|
55
80
|
* If a looping sound is playing, it will be stopped immediately.
|
|
56
81
|
*/
|
|
57
82
|
stop(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Sets the volume for background music only.
|
|
85
|
+
* @param value 0.0 to 1.0
|
|
86
|
+
*/
|
|
87
|
+
setMusicVolume(value: number): void;
|
|
88
|
+
/**
|
|
89
|
+
* Sets the volume for sound effects only.
|
|
90
|
+
* @param value 0.0 to 1.0
|
|
91
|
+
*/
|
|
92
|
+
setSFXVolume(value: number): void;
|
|
93
|
+
/**
|
|
94
|
+
* Sets the Global Master Volume (affects both Music and SFX).
|
|
95
|
+
* @param value 0.0 to 1.0
|
|
96
|
+
*/
|
|
97
|
+
set volume(value: number);
|
|
98
|
+
get volume(): number;
|
|
58
99
|
}
|
|
59
100
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,YAAY,EAAE,GAAG,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,GAAG,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAa;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,iBAAiB;IAC5B,YAAY,EAAE,GAAG,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,GAAG,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAa;IAGzB,UAAU,EAAE,GAAG,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;gBAEV,EACV,YAAY,EACZ,KAAK,EACL,QAAQ,GACT,EAAE;QACD,YAAY,EAAE,GAAG,GAAG,IAAI,CAAC;QACzB,KAAK,EAAE,GAAG,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB;IAgDD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,mBAAmB;IA8C3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuDxB,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG;IA0EjC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAoI7C,WAAW;IAIX,cAAc;IAId;;;OAGG;IACH,IAAI;IAUJ;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM;IAW5B;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM;IAU1B;;;OAGG;IACH,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAQvB;IAGD,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audiosprites",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "audio sprites for react native ios, android and web",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"typecheck": "tsc",
|
|
37
37
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
38
38
|
"clean": "del-cli lib",
|
|
39
|
+
"types:sync": "node scripts/generate-audio-types.mjs",
|
|
40
|
+
"prebuild": "npm run types:sync",
|
|
39
41
|
"prepare": "bob build",
|
|
40
42
|
"release:alpha": "release-it --preRelease=alpha",
|
|
41
43
|
"release": "release-it --only-version",
|
|
@@ -81,11 +83,13 @@
|
|
|
81
83
|
"@eslint/eslintrc": "^3.3.1",
|
|
82
84
|
"@eslint/js": "^9.35.0",
|
|
83
85
|
"@evilmartians/lefthook": "^1.12.3",
|
|
86
|
+
"@react-native-community/slider": "^5.1.1",
|
|
84
87
|
"@react-native/babel-preset": "0.81.1",
|
|
85
88
|
"@react-native/eslint-config": "^0.81.1",
|
|
86
89
|
"@release-it/conventional-changelog": "^10.0.1",
|
|
87
90
|
"@types/jest": "^29.5.14",
|
|
88
91
|
"@types/react": "^19.1.12",
|
|
92
|
+
"arktype": "^2.1.29",
|
|
89
93
|
"commitlint": "^19.8.1",
|
|
90
94
|
"del-cli": "^6.0.0",
|
|
91
95
|
"eslint": "^9.35.0",
|
|
@@ -95,9 +99,10 @@
|
|
|
95
99
|
"prettier": "^3.6.2",
|
|
96
100
|
"react": "19.1.0",
|
|
97
101
|
"react-native": "0.81.5",
|
|
98
|
-
"react-native-audio-api": "
|
|
102
|
+
"react-native-audio-api": "0.10.1",
|
|
99
103
|
"react-native-builder-bob": "^0.40.13",
|
|
100
104
|
"release-it": "^19.0.4",
|
|
105
|
+
"ts-morph": "^27.0.2",
|
|
101
106
|
"typescript": "^5.9.2"
|
|
102
107
|
},
|
|
103
108
|
"peerDependencies": {
|
package/src/index.tsx
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
3
3
|
* Requires an AudioContext and fetch to be injected.
|
|
4
4
|
* Uses AudioBufferQueueSourceNode and buffer splitting for mobile stability.
|
|
5
5
|
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Defines the available audio routing channels.
|
|
9
|
+
* - 'sfx': Short sound effects (coins, jumps, UI). High priority, usually usually non-looping.
|
|
10
|
+
* - 'music': Background tracks. Lower priority, usually looping, separate volume control.
|
|
11
|
+
*/
|
|
12
|
+
export type AudioChannel = 'sfx' | 'music';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for playing a specific sound sprite.
|
|
16
|
+
*/
|
|
17
|
+
export interface PlayOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Specifies which mixer channel to route the audio through.
|
|
20
|
+
* Use 'music' for BGM to ensure it responds to music volume settings.
|
|
21
|
+
* @default 'sfx'
|
|
22
|
+
*/
|
|
23
|
+
channel?: AudioChannel;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Force the sound to loop (or not), overriding the setting
|
|
27
|
+
* defined in the original audiosprite JSON manifest.
|
|
28
|
+
*/
|
|
29
|
+
loop?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
6
32
|
export class AudioSpritePlayer {
|
|
7
33
|
audioContext: any | null;
|
|
8
34
|
fetch: any | null;
|
|
@@ -15,6 +41,11 @@ export class AudioSpritePlayer {
|
|
|
15
41
|
private sourcePool: any[] = []; // NEW: Pool for non-looping sources
|
|
16
42
|
private maxPoolSize: number = 5; // Adjust this based on testing (5 is a good start)
|
|
17
43
|
|
|
44
|
+
// NEW: The Mixer
|
|
45
|
+
public masterGain: any;
|
|
46
|
+
public sfxGain: any;
|
|
47
|
+
public musicGain: any;
|
|
48
|
+
|
|
18
49
|
constructor({
|
|
19
50
|
audioContext,
|
|
20
51
|
fetch,
|
|
@@ -55,6 +86,20 @@ export class AudioSpritePlayer {
|
|
|
55
86
|
// @ts-ignore
|
|
56
87
|
this.audioContext = new AudioContext();
|
|
57
88
|
}
|
|
89
|
+
|
|
90
|
+
// 1. Create Master Output
|
|
91
|
+
this.masterGain = this.audioContext.createGain();
|
|
92
|
+
this.masterGain.gain.value = 1.0;
|
|
93
|
+
this.masterGain.connect(this.audioContext.destination);
|
|
94
|
+
|
|
95
|
+
// 2. Create Channels
|
|
96
|
+
this.sfxGain = this.audioContext.createGain();
|
|
97
|
+
this.sfxGain.gain.value = 1.0;
|
|
98
|
+
this.sfxGain.connect(this.masterGain); // Connect to Master
|
|
99
|
+
|
|
100
|
+
this.musicGain = this.audioContext.createGain();
|
|
101
|
+
this.musicGain.gain.value = 1.0;
|
|
102
|
+
this.musicGain.connect(this.masterGain); // Connect to Master
|
|
58
103
|
}
|
|
59
104
|
|
|
60
105
|
/**
|
|
@@ -133,7 +178,7 @@ export class AudioSpritePlayer {
|
|
|
133
178
|
if (this.platform === 'web') {
|
|
134
179
|
// Web logic remains simple: always create a standard AudioBufferSourceNode
|
|
135
180
|
const source = this.audioContext.createBufferSource();
|
|
136
|
-
source.connect(this.audioContext.destination);
|
|
181
|
+
// source.connect(this.audioContext.destination);
|
|
137
182
|
return source;
|
|
138
183
|
}
|
|
139
184
|
|
|
@@ -153,7 +198,7 @@ export class AudioSpritePlayer {
|
|
|
153
198
|
return null;
|
|
154
199
|
}
|
|
155
200
|
source = this.audioContext.createBufferQueueSource();
|
|
156
|
-
source.connect(this.audioContext.destination);
|
|
201
|
+
// source.connect(this.audioContext.destination);
|
|
157
202
|
// console.log('Created new source. Pool size:', this.sourcePool.length);
|
|
158
203
|
} else {
|
|
159
204
|
// If pool is full, we might have to block or fail.
|
|
@@ -258,7 +303,7 @@ export class AudioSpritePlayer {
|
|
|
258
303
|
}
|
|
259
304
|
}
|
|
260
305
|
|
|
261
|
-
play(soundName: string) {
|
|
306
|
+
play(soundName: string, options?: PlayOptions) {
|
|
262
307
|
if (!this.audioBuffer || !this.manifest) {
|
|
263
308
|
console.warn('Audio sprite not loaded. Call load() first.');
|
|
264
309
|
return;
|
|
@@ -283,6 +328,15 @@ export class AudioSpritePlayer {
|
|
|
283
328
|
return;
|
|
284
329
|
}
|
|
285
330
|
|
|
331
|
+
// 1. Determine Channel (Default to 'sfx')
|
|
332
|
+
const channel = options?.channel || 'sfx';
|
|
333
|
+
const targetNode = channel === 'music' ? this.musicGain : this.sfxGain;
|
|
334
|
+
|
|
335
|
+
// 2. Determine Loop (Options override Manifest)
|
|
336
|
+
// defined in your existing code as: const sound = this.manifest.sprite[soundName];
|
|
337
|
+
// const manifestLoop = sound[2];
|
|
338
|
+
const loop = options?.loop !== undefined ? options.loop : sound[2];
|
|
339
|
+
|
|
286
340
|
let source: any;
|
|
287
341
|
const spriteBuffer = this.spriteBufferCache[soundName];
|
|
288
342
|
|
|
@@ -302,13 +356,12 @@ export class AudioSpritePlayer {
|
|
|
302
356
|
return;
|
|
303
357
|
}
|
|
304
358
|
|
|
305
|
-
const loop = sound[2];
|
|
306
|
-
|
|
307
359
|
if (loop) {
|
|
308
360
|
// Always use AudioBufferQueueSourceNode
|
|
309
361
|
source = this.audioContext.createBufferQueueSource();
|
|
310
362
|
source.enqueueBuffer(spriteBuffer);
|
|
311
|
-
source.connect(this.audioContext.destination);
|
|
363
|
+
// source.connect(this.audioContext.destination);
|
|
364
|
+
source.connect(targetNode);
|
|
312
365
|
|
|
313
366
|
// Manual looping using onEnded
|
|
314
367
|
const loopHandler = () => {
|
|
@@ -332,6 +385,10 @@ export class AudioSpritePlayer {
|
|
|
332
385
|
source = this._getOrCreateSourceNode();
|
|
333
386
|
if (!source) return; // Dropped sound because pool was full
|
|
334
387
|
|
|
388
|
+
// Reconnect to the correct channel (since pooled nodes might have been connected elsewhere)
|
|
389
|
+
source.disconnect();
|
|
390
|
+
source.connect(targetNode);
|
|
391
|
+
|
|
335
392
|
// Must re-enqueue the buffer since the source was reused
|
|
336
393
|
source.enqueueBuffer(spriteBuffer);
|
|
337
394
|
|
|
@@ -350,9 +407,10 @@ export class AudioSpritePlayer {
|
|
|
350
407
|
}
|
|
351
408
|
|
|
352
409
|
source.buffer = spriteBuffer;
|
|
353
|
-
source.connect(this.audioContext.destination);
|
|
410
|
+
// source.connect(this.audioContext.destination);
|
|
411
|
+
source.connect(targetNode);
|
|
354
412
|
|
|
355
|
-
const loop = sound[2]; // audiosprite stores loop as the third element in the array
|
|
413
|
+
// const loop = sound[2]; // audiosprite stores loop as the third element in the array
|
|
356
414
|
if (loop) {
|
|
357
415
|
source.loop = true;
|
|
358
416
|
source.loopStart = 0; // Relative to the spriteBuffer
|
|
@@ -398,4 +456,52 @@ export class AudioSpritePlayer {
|
|
|
398
456
|
console.log('RNAS: No looping audio to stop.');
|
|
399
457
|
}
|
|
400
458
|
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Sets the volume for background music only.
|
|
462
|
+
* @param value 0.0 to 1.0
|
|
463
|
+
*/
|
|
464
|
+
setMusicVolume(value: number) {
|
|
465
|
+
if (this.musicGain) {
|
|
466
|
+
// secure against uninitialized context
|
|
467
|
+
this.musicGain.gain.setTargetAtTime(
|
|
468
|
+
value,
|
|
469
|
+
this.audioContext.currentTime,
|
|
470
|
+
0.02
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Sets the volume for sound effects only.
|
|
477
|
+
* @param value 0.0 to 1.0
|
|
478
|
+
*/
|
|
479
|
+
setSFXVolume(value: number) {
|
|
480
|
+
if (this.sfxGain) {
|
|
481
|
+
this.sfxGain.gain.setTargetAtTime(
|
|
482
|
+
value,
|
|
483
|
+
this.audioContext.currentTime,
|
|
484
|
+
0.02
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Sets the Global Master Volume (affects both Music and SFX).
|
|
491
|
+
* @param value 0.0 to 1.0
|
|
492
|
+
*/
|
|
493
|
+
set volume(value: number) {
|
|
494
|
+
if (this.masterGain) {
|
|
495
|
+
this.masterGain.gain.setTargetAtTime(
|
|
496
|
+
value,
|
|
497
|
+
this.audioContext.currentTime,
|
|
498
|
+
0.02
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Master Volume getter
|
|
504
|
+
get volume(): number {
|
|
505
|
+
return this.masterGain?.gain?.value ?? 1.0;
|
|
506
|
+
}
|
|
401
507
|
}
|