{"id":33510058,"url":"https://github.com/qalqi/react-native-audiosprites","last_synced_at":"2025-11-26T04:03:29.388Z","repository":{"id":322668773,"uuid":"1090149098","full_name":"qalqi/react-native-audiosprites","owner":"qalqi","description":"React Native player for audio sprites generated by the 'audiosprite' tool. Supports ios, android and web","archived":false,"fork":false,"pushed_at":"2025-11-22T10:03:17.000Z","size":11365,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-22T11:24:49.157Z","etag":null,"topics":["android","audiosprite","expo","games","ios","react-native"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/react-native-audiosprites","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qalqi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-05T09:35:58.000Z","updated_at":"2025-11-22T10:03:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"b9a3fc75-2f1b-413f-b5ef-34c71b298ecf","html_url":"https://github.com/qalqi/react-native-audiosprites","commit_stats":null,"previous_names":["qalqi/react-native-audiosprites"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/qalqi/react-native-audiosprites","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalqi%2Freact-native-audiosprites","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalqi%2Freact-native-audiosprites/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalqi%2Freact-native-audiosprites/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalqi%2Freact-native-audiosprites/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qalqi","download_url":"https://codeload.github.com/qalqi/react-native-audiosprites/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalqi%2Freact-native-audiosprites/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286079811,"owners_count":27282121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-26T02:00:06.075Z","response_time":193,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","audiosprite","expo","games","ios","react-native"],"created_at":"2025-11-26T04:03:23.402Z","updated_at":"2025-11-26T04:03:29.374Z","avatar_url":"https://github.com/qalqi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![react-native-audiosprites_poster](react-native-audiosprites_poster.jpg)\n\n# react-native-audiosprites\n\nA universal player for audio sprites generated by the 'audiosprite' tool.\nSupports playing multiple sounds at same time!\n\n## Installation\n\n```sh\nnpm install react-native-audiosprites\n```\n\n```sh\nyarn add react-native-audiosprites\n```\n\n## Usage\n\nFirst, you need to generate an audio sprite and a JSON manifest file using the `audiosprite` tool.\n\nAssuming you have [`audiosprite`](https://www.npmjs.com/package/audiosprite) installed globally:\n\n```sh\naudiosprite --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\n```\n\nThis command will generate `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a`, and `mygameaudio.ac3` in the `src/__tests__/sounds/` directory.\n\n### Looping Sounds\n\nYou 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.\n\nFor example, to loop the `bg_music` sound, you would use the following command:\n\n```sh\naudiosprite --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\n```\n\nWhen you play a looping sound, it will play continuously until you stop it using the `player.stop()` method. The looping functionality is supported on both web and mobile platforms.\n\nThen, you can use the `AudioSpritePlayer` to play the sounds from the sprite.\n\n### Browser Environment\n\n```typescript\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\n\nconst player = new AudioSpritePlayer({\n  platform: 'web',\n});\n\nasync function playSound(soundName: string) {\n  try {\n    // Load the audio sprite manifest and audio files\n    // Adjust the path to your audiosprite.json file\n    await player.load('./src/__tests__/sounds/mygameaudio.json');\n    console.log('Audio sprite loaded successfully.');\n\n    // Play a sound from the spritemap\n    player.play(soundName);\n    console.log(`Playing sound: ${soundName}`);\n  } catch (error) {\n    console.error('Error playing sound:', error);\n  }\n}\n\nfunction stopSound() {\n  player.stop();\n  console.log('Stopped looping sound.');\n}\n\n// Example usage:\nplaySound('Sound_1');\n// playSound('Sound_2');\n// To stop a looping sound:\n// stopSound();\n```\n\n### React Native Environment\n\nFor React Native, you'll need `react-native-audio-api` and `expo-asset` to handle audio playback and asset loading.\n\nFirst, install the dependencies:\n\n```sh\nnpm install react-native-audio-api expo-asset expo-file-system\n# or\nyarn add react-native-audio-api expo-asset expo-file-system\n```\n\nChange `metro.config.js` as per `react-native-audio-api` documentation: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started\n\n```js\nmodule.exports = wrapWithAudioAPIMetroConfig(config);\n```\n\nThen, you can use it in your component:\n\n```typescript\nimport { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\nimport { AudioManager, AudioContext } from 'react-native-audio-api';\nimport { useEffect, useState, useRef } from 'react';\nimport { Asset } from 'expo-asset';\nimport { fetch } from 'expo/fetch';\nimport manifest from '../assets/mygameaudio.json';\n\n// Import the audio asset\nconst audioAsset = require('../assets/mygameaudio.mp3');\n\nexport default function App() {\n  const [isLoaded, setIsLoaded] = useState(false);\n  const playerRef = useRef\u003cAudioSpritePlayer | null\u003e(null);\n\n  useEffect(() =\u003e {\n    const loadPlayer = async () =\u003e {\n      const asset = Asset.fromModule(audioAsset);\n      await asset.downloadAsync();\n      const audioUri = asset.localUri || asset.uri;\n\n      if (!audioUri) {\n        console.error('Failed to get audio URI.');\n        return;\n      }\n\n      if (Platform.OS === 'ios') {\n        try {\n          await AudioManager.setAudioSessionOptions({\n            iosCategory: 'playback',\n            iosOptions: ['mixWithOthers'],\n          });\n          await AudioManager.setAudioSessionActivity(true);\n        } catch (e) {\n          console.error('Failed to configure AudioSession options:', e);\n        }\n      }\n\n      const audioContext = new AudioContext();\n      const audioPlayer = new AudioSpritePlayer({\n        audioContext,\n        fetch: fetch.bind(globalThis),\n        platform: Platform.OS,\n      });\n\n      try {\n        await audioPlayer.load(manifest, audioUri);\n        playerRef.current = audioPlayer;\n        setIsLoaded(true);\n        console.log('Audio sprite loaded successfully.');\n      } catch (error) {\n        console.error('Failed to load audio sprite:', error);\n      }\n    };\n\n    loadPlayer();\n  }, []);\n\n  const playSound = (soundName: string) =\u003e {\n    const player = playerRef.current;\n    if (player \u0026\u0026 isLoaded) {\n      player.play(soundName);\n      console.log(`Playing sound: ${soundName}`);\n    } else {\n      console.warn('Player not loaded yet.');\n    }\n  };\n\n  const stopBGM = () =\u003e {\n    const player = playerRef.current;\n    if (player) {\n      player.stop();\n    }\n  };\n\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eAudioSprite Player Example\u003c/Text\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e loadPlayer()}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eLoad Player\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_1')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003ePlay Sound 1\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_2')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003ePlay Sound 2\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('bg_loop')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003ePlay Background Loop\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={stopBGM}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eStop BGM\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    backgroundColor: '#DDDDDD',\n    padding: 10,\n    marginVertical: 5,\n    borderRadius: 5,\n  },\n  buttonText: {\n    color: '#000000',\n    textAlign: 'center',\n  },\n});\n```\n\n## Inspiration\n\nhttps://github.com/goldfire/howler.js\nGenerated json also works with new Howl({\nsprite: {\nkey1: [offset, duration, (loop)]\n},\n});\n\n## Contributing\n\n- [Development workflow](CONTRIBUTING.md#development-workflow)\n- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)\n- [Code of conduct](CODE_OF_CONDUCT.md)\n\n## License\n\nMIT\n\n## Credits\n\n[Shaker, Woda, Conga, Bongo, Templeblock.wav](https://freesound.org/people/kwazi/sounds/34115/) by [kwazi](https://freesound.org/people/kwazi/) | License: [Attribution 3.0](http://creativecommons.org/licenses/by/3.0/)\n\nMade with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)\n\n---\n\n# Translations\n\n## Spanish\n\n![react-native-audiosprites_poster](react-native-audiosprites_poster.jpg)\n\n# react-native-audiosprites\n\nUn reproductor universal para sprites de audio generados por la herramienta 'audiosprite'.\n¡Soporta la reproducción de múltiples sonidos al mismo tiempo!\n\n## Instalación\n\n```sh\nnpm install react-native-audiosprites\n```\n\n```sh\nyarn add react-native-audiosprites\n```\n\n## Uso\n\nPrimero, necesitas generar un sprite de audio y un archivo de manifiesto JSON usando la herramienta `audiosprite`.\n\nAsumiendo que tienes [`audiosprite`](https://www.npmjs.com/package/audiosprite) instalado globalmente:\n\n```sh\naudiosprite --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\n```\n\nEste comando generará `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a` y `mygameaudio.ac3` en el directorio `src/__tests__/sounds/`.\n\n### Sonidos en Bucle\n\nPuedes 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.\n\nPor ejemplo, para repetir el sonido `bg_music`, usarías el siguiente comando:\n\n```sh\naudiosprite --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\n```\n\nCuando reproduces un sonido en bucle, se reproducirá continuamente hasta que lo detengas usando el método `player.stop()`. La funcionalidad de bucle es compatible tanto en plataformas web como móviles.\n\nLuego, puedes usar el `AudioSpritePlayer` para reproducir los sonidos del sprite.\n\n### Entorno del Navegador\n\n```typescript\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\n\nconst player = new AudioSpritePlayer({\n  platform: 'web',\n});\n\nasync function playSound(soundName: string) {\n  try {\n    // Carga el manifiesto del sprite de audio y los archivos de audio\n    // Ajusta la ruta a tu archivo audiosprite.json\n    await player.load('./src/__tests__/sounds/mygameaudio.json');\n    console.log('Sprite de audio cargado exitosamente.');\n\n    // Reproduce un sonido del spritemap\n    player.play(soundName);\n    console.log(`Reproduciendo sonido: ${soundName}`);\n  } catch (error) {\n    console.error('Error al reproducir el sonido:', error);\n  }\n}\n\nfunction stopSound() {\n  player.stop();\n  console.log('Sonido en bucle detenido.');\n}\n\n// Ejemplo de uso:\nplaySound('Sound_1');\n// playSound('Sound_2');\n// Para detener un sonido en bucle:\n// stopSound();\n```\n\n### Entorno de React Native\n\nPara React Native, necesitarás `react-native-audio-api` y `expo-asset` para manejar la reproducción de audio y la carga de activos.\n\nPrimero, instala las dependencias:\n\n```sh\nnpm install react-native-audio-api expo-asset expo-file-system\n# o\nyarn add react-native-audio-api expo-asset expo-file-system\n```\n\nCambia `metro.config.js` según la documentación de `react-native-audio-api`: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started\n\n```js\nmodule.exports = wrapWithAudioAPIMetroConfig(config);\n```\n\nLuego, puedes usarlo en tu componente:\n\n```typescript\nimport { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\nimport { AudioManager, AudioContext } from 'react-native-audio-api';\nimport { useEffect, useState, useRef } from 'react';\nimport { Asset } from 'expo-asset';\nimport { fetch } from 'expo/fetch';\nimport manifest from '../assets/mygameaudio.json';\n\n// Importa el activo de audio\nconst audioAsset = require('../assets/mygameaudio.mp3');\n\nexport default function App() {\n  const [isLoaded, setIsLoaded] = useState(false);\n  const playerRef = useRef\u003cAudioSpritePlayer | null\u003e(null);\n\n  useEffect(() =\u003e {\n    const loadPlayer = async () =\u003e {\n      const asset = Asset.fromModule(audioAsset);\n      await asset.downloadAsync();\n      const audioUri = asset.localUri || asset.uri;\n\n      if (!audioUri) {\n        console.error('No se pudo obtener la URI del audio.');\n        return;\n      }\n\n      if (Platform.OS === 'ios') {\n        try {\n          await AudioManager.setAudioSessionOptions({\n            iosCategory: 'playback',\n            iosOptions: ['mixWithOthers'],\n          });\n          await AudioManager.setAudioSessionActivity(true);\n        } catch (e) {\n          console.error('Error al configurar las opciones de AudioSession:', e);\n        }\n      }\n\n      const audioContext = new AudioContext();\n      const audioPlayer = new AudioSpritePlayer({\n        audioContext,\n        fetch: fetch.bind(globalThis),\n        platform: Platform.OS,\n      });\n\n      try {\n        await audioPlayer.load(manifest, audioUri);\n        playerRef.current = audioPlayer;\n        setIsLoaded(true);\n        console.log('Sprite de audio cargado exitosamente.');\n      } catch (error) {\n        console.error('Error al cargar el sprite de audio:', error);\n      }\n    };\n\n    loadPlayer();\n  }, []);\n\n  const playSound = (soundName: string) =\u003e {\n    const player = playerRef.current;\n    if (player \u0026\u0026 isLoaded) {\n      player.play(soundName);\n      console.log(`Reproduciendo sonido: ${soundName}`);\n    } else {\n      console.warn('El reproductor aún no se ha cargado.');\n    }\n  };\n\n  const stopBGM = () =\u003e {\n    const player = playerRef.current;\n    if (player) {\n      player.stop();\n    }\n  };\n\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eEjemplo de AudioSprite Player\u003c/Text\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e loadPlayer()}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eCargar Reproductor\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_1')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eReproducir Sonido 1\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_2')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eReproducir Sonido 2\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('bg_loop')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eReproducir Bucle de Fondo\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={stopBGM}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eDetener BGM\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    backgroundColor: '#DDDDDD',\n    padding: 10,\n    marginVertical: 5,\n    borderRadius: 5,\n  },\n  buttonText: {\n    color: '#000000',\n    textAlign: 'center',\n  },\n});\n```\n\n## Inspiración\n\nhttps://github.com/goldfire/howler.js\nEl json generado también funciona con new Howl({\nsprite: {\nkey1: [offset, duration, (loop)]\n},\n});\n\n## Contribuciones\n\n- [Flujo de trabajo de desarrollo](CONTRIBUTING.md#development-workflow)\n- [Enviar una pull request](CONTRIBUTING.md#sending-a-pull-request)\n- [Código de conducta](CODE_OF_CONDUCT.md)\n\n## Licencia\n\nMIT\n\n## Créditos\n\n[Shaker, Woda, Conga, Bongo, Templeblock.wav](https://freesound.org/people/kwazi/sounds/34115/) por [kwazi](https://freesound.org/people/kwazi/) | Licencia: [Atribución 3.0](http://creativecommons.org/licenses/by/3.0/)\n\nHecho con [create-react-native-library](https://github.com/callstack/react-native-builder-bob)\n\n## Russian\n\n![react-native-audiosprites_poster](react-native-audiosprites_poster.jpg)\n\n# react-native-audiosprites\n\nУниверсальный проигрыватель для аудио-спрайтов, созданных с помощью инструмента 'audiosprite'.\nПоддерживает одновременное воспроизведение нескольких звуков!\n\n## Установка\n\n```sh\nnpm install react-native-audiosprites\n```\n\n```sh\nyarn add react-native-audiosprites\n```\n\n## Использование\n\nСначала вам нужно создать аудио-спрайт и файл манифеста JSON с помощью инструмента `audiosprite`.\n\nПредполагая, что у вас глобально установлен [`audiosprite`](https://www.npmjs.com/package/audiosprite):\n\n```sh\naudiosprite --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\n```\n\nЭта команда создаст `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a` и `mygameaudio.ac3` в каталоге `src/__tests__/sounds/`.\n\n### Зацикленные звуки\n\nВы можете создавать зацикленные звуки, используя опцию `--loop` с командой `audiosprite`. Значением опции `--loop` должно быть имя звука, который вы хотите зациклить.\n\nНапример, чтобы зациклить звук `bg_music`, вы должны использовать следующую команду:\n\n```sh\naudiosprite --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\n```\n\nКогда вы воспроизводите зацикленный звук, он будет воспроизводиться непрерывно, пока вы не остановите его с помощью метода `player.stop()`. Функция зацикливания поддерживается как на веб-, так и на мобильных платформах.\n\nЗатем вы можете использовать `AudioSpritePlayer` для воспроизведения звуков из спрайта.\n\n### Среда браузера\n\n```typescript\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\n\nconst player = new AudioSpritePlayer({\n  platform: 'web',\n});\n\nasync function playSound(soundName: string) {\n  try {\n    // Загрузите манифест аудио-спрайта и аудиофайлы\n    // Укажите правильный путь к вашему файлу audiosprite.json\n    await player.load('./src/__tests__/sounds/mygameaudio.json');\n    console.log('Аудио-спрайт успешно загружен.');\n\n    // Воспроизведите звук из spritemap\n    player.play(soundName);\n    console.log(`Воспроизведение звука: ${soundName}`);\n  } catch (error) {\n    console.error('Ошибка воспроизведения звука:', error);\n  }\n}\n\nfunction stopSound() {\n  player.stop();\n  console.log('Зацикленный звук остановлен.');\n}\n\n// Пример использования:\nplaySound('Sound_1');\n// playSound('Sound_2');\n// Чтобы остановить зацикленный звук:\n// stopSound();\n```\n\n### Среда React Native\n\nДля React Native вам понадобятся `react-native-audio-api` и `expo-asset` для обработки воспроизведения аудио и загрузки ресурсов.\n\nСначала установите зависимости:\n\n```sh\nnpm install react-native-audio-api expo-asset expo-file-system\n# или\nyarn add react-native-audio-api expo-asset expo-file-system\n```\n\nИзмените `metro.config.js` в соответствии с документацией `react-native-audio-api`: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started\n\n```js\nmodule.exports = wrapWithAudioAPIMetroConfig(config);\n```\n\nЗатем вы можете использовать его в своем компоненте:\n\n```typescript\nimport { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\nimport { AudioManager, AudioContext } from 'react-native-audio-api';\nimport { useEffect, useState, useRef } from 'react';\nimport { Asset } from 'expo-asset';\nimport { fetch } from 'expo/fetch';\nimport manifest from '../assets/mygameaudio.json';\n\n// Импортируйте аудио-ресурс\nconst audioAsset = require('../assets/mygameaudio.mp3');\n\nexport default function App() {\n  const [isLoaded, setIsLoaded] = useState(false);\n  const playerRef = useRef\u003cAudioSpritePlayer | null\u003e(null);\n\n  useEffect(() =\u003e {\n    const loadPlayer = async () =\u003e {\n      const asset = Asset.fromModule(audioAsset);\n      await asset.downloadAsync();\n      const audioUri = asset.localUri || asset.uri;\n\n      if (!audioUri) {\n        console.error('Не удалось получить URI аудио.');\n        return;\n      }\n\n      if (Platform.OS === 'ios') {\n        try {\n          await AudioManager.setAudioSessionOptions({\n            iosCategory: 'playback',\n            iosOptions: ['mixWithOthers'],\n          });\n          await AudioManager.setAudioSessionActivity(true);\n        } catch (e) {\n          console.error('Не удалось настроить параметры AudioSession:', e);\n        }\n      }\n\n      const audioContext = new AudioContext();\n      const audioPlayer = new AudioSpritePlayer({\n        audioContext,\n        fetch: fetch.bind(globalThis),\n        platform: Platform.OS,\n      });\n\n      try {\n        await audioPlayer.load(manifest, audioUri);\n        playerRef.current = audioPlayer;\n        setIsLoaded(true);\n        console.log('Аудио-спрайт успешно загружен.');\n      } catch (error) {\n        console.error('Не удалось загрузить аудио-спрайт:', error);\n      }\n    };\n\n    loadPlayer();\n  }, []);\n\n  const playSound = (soundName: string) =\u003e {\n    const player = playerRef.current;\n    if (player \u0026\u0026 isLoaded) {\n      player.play(soundName);\n      console.log(`Воспроизведение звука: ${soundName}`);\n    } else {\n      console.warn('Проигрыватель еще не загружен.');\n    }\n  };\n\n  const stopBGM = () =\u003e {\n    const player = playerRef.current;\n    if (player) {\n      player.stop();\n    }\n  };\n\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eПример AudioSprite Player\u003c/Text\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e loadPlayer()}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eЗагрузить проигрыватель\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_1')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eВоспроизвести звук 1\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_2')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eВоспроизвести звук 2\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('bg_loop')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eВоспроизвести фоновый цикл\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={stopBGM}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eОстановить фоновую музыку\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    backgroundColor: '#DDDDDD',\n    padding: 10,\n    marginVertical: 5,\n    borderRadius: 5,\n  },\n  buttonText: {\n    color: '#000000',\n    textAlign: 'center',\n  },\n});\n```\n\n## Вдохновение\n\nhttps://github.com/goldfire/howler.js\nСгенерированный json также работает с new Howl({\nsprite: {\nkey1: [offset, duration, (loop)]\n},\n});\n\n## Участие\n\n- [Рабочий процесс разработки](CONTRIBUTING.md#development-workflow)\n- [Отправка pull request](CONTRIBUTING.md#sending-a-pull-request)\n- [Кодекс поведения](CODE_OF_CONDUCT.md)\n\n## Лицензия\n\nMIT\n\n## Кредиты\n\n[Shaker, Woda, Conga, Bongo, Templeblock.wav](https://freesound.org/people/kwazi/sounds/34115/) от [kwazi](https://freesound.org/people/kwazi/) | Лицензия: [Attribution 3.0](http://creativecommons.org/licenses/by/3.0/)\n\nСделано с помощью [create-react-native-library](https://github.com/callstack/react-native-builder-bob)\n\n## Hindi\n\n![react-native-audiosprites_poster](react-native-audiosprites_poster.jpg)\n\n# react-native-audiosprites\n\n'ऑडियोस्प्राइट' टूल द्वारा उत्पन्न ऑडियो स्प्राइट्स के लिए एक सार्वभौमिक खिलाड़ी।\nएक ही समय में कई ध्वनियाँ बजाने का समर्थन करता है!\n\n## स्थापना\n\n```sh\nnpm install react-native-audiosprites\n```\n\n```sh\nyarn add react-native-audiosprites\n```\n\n## उपयोग\n\nसबसे पहले, आपको `audiosprite` टूल का उपयोग करके एक ऑडियो स्प्राइट और एक JSON मैनिफ़ेस्ट फ़ाइल उत्पन्न करने की आवश्यकता है।\n\nमान लें कि आपके पास विश्व स्तर पर [`audiosprite`](https://www.npmjs.com/package/audiosprite) स्थापित है:\n\n```sh\naudiosprite --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\n```\n\nयह कमांड `src/__tests__/sounds/` डायरेक्टरी में `mygameaudio.json`, `mygameaudio.mp3`, `mygameaudio.ogg`, `mygameaudio.m4a`, और `mygameaudio.ac3` उत्पन्न करेगा।\n\n### लूपिंग ध्वनियाँ\n\nआप `audiosprite` कमांड के साथ `--loop` विकल्प का उपयोग करके लूपिंग ध्वनियाँ बना सकते हैं। `--loop` विकल्प का मान उस ध्वनि का नाम होना चाहिए जिसे आप लूप करना चाहते हैं।\n\nउदाहरण के लिए, `bg_music` ध्वनि को लूप करने के लिए, आप निम्न कमांड का उपयोग करेंगे:\n\n```sh\naudiosprite --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\n```\n\nजब आप एक लूपिंग ध्वनि बजाते हैं, तो यह तब तक लगातार बजेगी जब तक आप इसे `player.stop()` विधि का उपयोग करके रोक नहीं देते। लूपिंग कार्यक्षमता वेब और मोबाइल दोनों प्लेटफार्मों पर समर्थित है।\n\nफिर, आप स्प्राइट से ध्वनियों को चलाने के लिए `AudioSpritePlayer` का उपयोग कर सकते हैं।\n\n### ब्राउज़र पर्यावरण\n\n```typescript\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\n\nconst player = new AudioSpritePlayer({\n  platform: 'web',\n});\n\nasync function playSound(soundName: string) {\n  try {\n    // ऑडियो स्प्राइट मैनिफ़ेस्ट और ऑडियो फ़ाइलें लोड करें\n    // अपनी audiosprite.json फ़ाइल का पथ समायोजित करें\n    await player.load('./src/__tests__/sounds/mygameaudio.json');\n    console.log('ऑडियो स्प्राइट सफलतापूर्वक लोड हो गया।');\n\n    // स्प्राइटमैप से एक ध्वनि चलाएं\n    player.play(soundName);\n    console.log(`ध्वनि बज रही है: ${soundName}`);\n  } catch (error) {\n    console.error('ध्वनि बजाने में त्रुटि:', error);\n  }\n}\n\nfunction stopSound() {\n  player.stop();\n  console.log('लूपिंग ध्वनि बंद हो गई।');\n}\n\n// उदाहरण उपयोग:\nplaySound('Sound_1');\n// playSound('Sound_2');\n// एक लूपिंग ध्वनि को रोकने के लिए:\n// stopSound();\n```\n\n### रिएक्ट नेटिव पर्यावरण\n\nरिएक्ट नेटिव के लिए, आपको ऑडियो प्लेबैक और एसेट लोडिंग को संभालने के लिए `react-native-audio-api` और `expo-asset` की आवश्यकता होगी।\n\nसबसे पहले, निर्भरताएँ स्थापित करें:\n\n```sh\nnpm install react-native-audio-api expo-asset expo-file-system\n# या\nyarn add react-native-audio-api expo-asset expo-file-system\n```\n\n`react-native-audio-api` दस्तावेज़ीकरण के अनुसार `metro.config.js` बदलें: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started\n\n```js\nmodule.exports = wrapWithAudioAPIMetroConfig(config);\n```\n\nफिर, आप इसे अपने घटक में उपयोग कर सकते हैं:\n\n```typescript\nimport { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\nimport { AudioManager, AudioContext } from 'react-native-audio-api';\nimport { useEffect, useState, useRef } from 'react';\nimport { Asset } from 'expo-asset';\nimport { fetch } from 'expo/fetch';\nimport manifest from '../assets/mygameaudio.json';\n\n// ऑडियो एसेट आयात करें\nconst audioAsset = require('../assets/mygameaudio.mp3');\n\nexport default function App() {\n  const [isLoaded, setIsLoaded] = useState(false);\n  const playerRef = useRef\u003cAudioSpritePlayer | null\u003e(null);\n\n  useEffect(() =\u003e {\n    const loadPlayer = async () =\u003e {\n      const asset = Asset.fromModule(audioAsset);\n      await asset.downloadAsync();\n      const audioUri = asset.localUri || asset.uri;\n\n      if (!audioUri) {\n        console.error('ऑडियो URI प्राप्त करने में विफल।');\n        return;\n      }\n\n      if (Platform.OS === 'ios') {\n        try {\n          await AudioManager.setAudioSessionOptions({\n            iosCategory: 'playback',\n            iosOptions: ['mixWithOthers'],\n          });\n          await AudioManager.setAudioSessionActivity(true);\n        } catch (e) {\n          console.error('ऑडियो सत्र विकल्प कॉन्फ़िगर करने में विफल:', e);\n        }\n      }\n\n      const audioContext = new AudioContext();\n      const audioPlayer = new AudioSpritePlayer({\n        audioContext,\n        fetch: fetch.bind(globalThis),\n        platform: Platform.OS,\n      });\n\n      try {\n        await audioPlayer.load(manifest, audioUri);\n        playerRef.current = audioPlayer;\n        setIsLoaded(true);\n        console.log('ऑडियो स्प्राइट सफलतापूर्वक लोड हो गया।');\n      } catch (error) {\n        console.error('ऑडियो स्प्राइट लोड करने में विफल:', error);\n      }\n    };\n\n    loadPlayer();\n  }, []);\n\n  const playSound = (soundName: string) =\u003e {\n    const player = playerRef.current;\n    if (player \u0026\u0026 isLoaded) {\n      player.play(soundName);\n      console.log(`ध्वनि बज रही है: ${soundName}`);\n    } else {\n      console.warn('खिलाड़ी अभी तक लोड नहीं हुआ है।');\n    }\n  };\n\n  const stopBGM = () =\u003e {\n    const player = playerRef.current;\n    if (player) {\n      player.stop();\n    }\n  };\n\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eऑडियोस्प्राइट प्लेयर उदाहरण\u003c/Text\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e loadPlayer()}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eखिलाड़ी लोड करें\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_1')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eध्वनि 1 चलाएं\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_2')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eध्वनि 2 चलाएं\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('bg_loop')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eपृष्ठभूमि लूप चलाएं\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={stopBGM}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003eबीजीएम रोकें\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    backgroundColor: '#DDDDDD',\n    padding: 10,\n    marginVertical: 5,\n    borderRadius: 5,\n  },\n  buttonText: {\n    color: '#000000',\n    textAlign: 'center',\n  },\n});\n```\n\n## प्रेरणा\n\nhttps://github.com/goldfire/howler.js\nउत्पन्न json new Howl({\nsprite: {\nkey1: [offset, duration, (loop)]\n},\n}); के साथ भी काम करता है।\n\n## योगदान\n\n- [विकास कार्यप्रवाह](CONTRIBUTING.md#development-workflow)\n- [एक पुल अनुरोध भेजना](CONTRIBUTING.md#sending-a-pull-request)\n- [आचार संहिता](CODE_OF_CONDUCT.md)\n\n## लाइसेंस\n\nएमआईटी\n\n## क्रेडिट\n\n[kwazi](https://freesound.org/people/kwazi/) द्वारा [शकर, वोडा, कोंगा, बोंगो, टेम्पलब्लॉक.wav](https://freesound.org/people/kwazi/sounds/34115/) | लाइसेंस: [एट्रिब्यूशन 3.0](http://creativecommons.org/licenses/by/3.0/)\n\n[create-react-native-library](https://github.com/callstack/react-native-builder-bob) के साथ बनाया गया\n\n## Chinese\n\n![react-native-audiosprites_poster](react-native-audiosprites_poster.jpg)\n\n# react-native-audiosprites\n\n一个用于播放由“audiosprite”工具生成的音频精灵的通用播放器。\n支持同时播放多种声音！\n\n## 安装\n\n```sh\nnpm install react-native-audiosprites\n```\n\n```sh\nyarn add react-native-audiosprites\n```\n\n## 用法\n\n首先，您需要使用 `audiosprite` 工具生成一个音频精灵和一个 JSON 清单文件。\n\n假设您已全局安装 [`audiosprite`](https://www.npmjs.com/package/audiosprite)：\n\n```sh\naudiosprite --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\n```\n\n此命令将在 `src/__tests__/sounds/` 目录中生成 `mygameaudio.json`、`mygameaudio.mp3`、`mygameaudio.ogg`、`mygameaudio.m4a` 和 `mygameaudio.ac3`。\n\n### 循环声音\n\n您可以使用 `audiosprite` 命令的 `--loop` 选项创建循环声音。`--loop` 选项的值应该是您想要循环的声音的名称。\n\n例如，要循环 `bg_music` 声音，您将使用以下命令：\n\n```sh\naudiosprite --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\n```\n\n当您播放循环声音时，它将连续播放，直到您使用 `player.stop()` 方法停止它。循环功能在 Web 和移动平台上都受支持。\n\n然后，您可以使用 `AudioSpritePlayer` 播放精灵中的声音。\n\n### 浏览器环境\n\n```typescript\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\n\nconst player = new AudioSpritePlayer({\n  platform: 'web',\n});\n\nasync function playSound(soundName: string) {\n  try {\n    // 加载音频精灵清单和音频文件\n    // 调整到您的 audiosprite.json 文件的路径\n    await player.load('./src/__tests__/sounds/mygameaudio.json');\n    console.log('音频精灵已成功加载。');\n\n    // 从 spritemap 播放声音\n    player.play(soundName);\n    console.log(`正在播放声音: ${soundName}`);\n  } catch (error) {\n    console.error('播放声音时出错:', error);\n  }\n}\n\nfunction stopSound() {\n  player.stop();\n  console.log('已停止循环声音。');\n}\n\n// 用法示例:\nplaySound('Sound_1');\n// playSound('Sound_2');\n// 停止循环声音:\n// stopSound();\n```\n\n### React Native 环境\n\n对于 React Native，您需要 `react-native-audio-api` 和 `expo-asset` 来处理音频播放和资产加载。\n\n首先，安装依赖项：\n\n```sh\nnpm install react-native-audio-api expo-asset expo-file-system\n# 或\nyarn add react-native-audio-api expo-asset expo-file-system\n```\n\n根据 `react-native-audio-api` 文档更改 `metro.config.js`：https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started\n\n```js\nmodule.exports = wrapWithAudioAPIMetroConfig(config);\n```\n\n然后，您可以在您的组件中使用它：\n\n```typescript\nimport { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';\nimport { AudioSpritePlayer } from 'react-native-audiosprites';\nimport { AudioManager, AudioContext } from 'react-native-audio-api';\nimport { useEffect, useState, useRef } from 'react';\nimport { Asset } from 'expo-asset';\nimport { fetch } from 'expo/fetch';\nimport manifest from '../assets/mygameaudio.json';\n\n// 导入音频资产\nconst audioAsset = require('../assets/mygameaudio.mp3');\n\nexport default function App() {\n  const [isLoaded, setIsLoaded] = useState(false);\n  const playerRef = useRef\u003cAudioSpritePlayer | null\u003e(null);\n\n  useEffect(() =\u003e {\n    const loadPlayer = async () =\u003e {\n      const asset = Asset.fromModule(audioAsset);\n      await asset.downloadAsync();\n      const audioUri = asset.localUri || asset.uri;\n\n      if (!audioUri) {\n        console.error('无法获取音频 URI。');\n        return;\n      }\n\n      if (Platform.OS === 'ios') {\n        try {\n          await AudioManager.setAudioSessionOptions({\n            iosCategory: 'playback',\n            iosOptions: ['mixWithOthers'],\n          });\n          await AudioManager.setAudioSessionActivity(true);\n        } catch (e) {\n          console.error('配置 AudioSession 选项失败:', e);\n        }\n      }\n\n      const audioContext = new AudioContext();\n      const audioPlayer = new AudioSpritePlayer({\n        audioContext,\n        fetch: fetch.bind(globalThis),\n        platform: Platform.OS,\n      });\n\n      try {\n        await audioPlayer.load(manifest, audioUri);\n        playerRef.current = audioPlayer;\n        setIsLoaded(true);\n        console.log('音频精灵已成功加载。');\n      } catch (error) {\n        console.error('加载音频精灵失败:', error);\n      }\n    };\n\n    loadPlayer();\n  }, []);\n\n  const playSound = (soundName: string) =\u003e {\n    const player = playerRef.current;\n    if (player \u0026\u0026 isLoaded) {\n      player.play(soundName);\n      console.log(`正在播放声音: ${soundName}`);\n    } else {\n      console.warn('播放器尚未加载。');\n    }\n  };\n\n  const stopBGM = () =\u003e {\n    const player = playerRef.current;\n    if (player) {\n      player.stop();\n    }\n  };\n\n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cText\u003eAudioSprite 播放器示例\u003c/Text\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e loadPlayer()}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003e加载播放器\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_1')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003e播放声音 1\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('Sound_2')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003e播放声音 2\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={() =\u003e playSound('bg_loop')}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003e播放背景循环\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n      \u003cTouchableOpacity\n        onPress={stopBGM}\n        style={styles.button}\n        disabled={!isLoaded}\n      \u003e\n        \u003cText style={styles.buttonText}\u003e停止背景音乐\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    backgroundColor: '#DDDDDD',\n    padding: 10,\n    marginVertical: 5,\n    borderRadius: 5,\n  },\n  buttonText: {\n    color: '#000000',\n    textAlign: 'center',\n  },\n});\n```\n\n## 灵感\n\nhttps://github.com/goldfire/howler.js\n生成的 json 也适用于 new Howl({\nsprite: {\nkey1: [offset, duration, (loop)]\n},\n});\n\n## 贡献\n\n- [开发工作流程](CONTRIBUTING.md#development-workflow)\n- [发送拉取请求](CONTRIBUTING.md#sending-a-pull-request)\n- [行为准则](CODE_OF_CONDUCT.md)\n\n## 执照\n\n麻省理工学院\n\n## 学分\n\n[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/)\n\n使用 [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 制作","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqalqi%2Freact-native-audiosprites","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqalqi%2Freact-native-audiosprites","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqalqi%2Freact-native-audiosprites/lists"}