Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/soymatudev/Pokedex-Fleek/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The useSound hook provides audio playback functionality for the PokéDex app. It handles Pokémon cry sounds, background music, and intro themes using expo-av. The hook includes error handling and audio configuration for iOS silent mode compatibility.

Import

import { useSound } from '../../hooks/useSound';

Usage

const { playSound, setupRouteOne, playIntro } = useSound();

// Play a Pokémon cry
await playSound('https://example.com/pokemon/25/cry.mp3');

// Setup background music
const [backgroundMusic, setBackgroundMusic] = useState(null);
await setupRouteOne(setBackgroundMusic);

// Play intro theme
const introSound = playIntro();

Return Values

The hook returns an object with the following methods:

playSound(uri)

Plays an audio file from a given URI, typically used for Pokémon cries. Parameters:
  • uri (string) - The URL or URI of the audio file to play
Returns: Promise<void> Error Handling: Errors during audio playback are caught and logged to the console:
try {
  const { sound } = await Audio.Sound.createAsync({ uri });
  await sound.playAsync();
} catch (error) {
  console.error("Error al reproducir el audio:", error);
}
Example:
// Play Pikachu's cry
await playSound('https://raw.githubusercontent.com/PokeAPI/cries/main/cries/pokemon/latest/25.ogg');

setupRouteOne(setBackgroundMusic)

Configures and plays the Route 1 background music loop. Parameters:
  • setBackgroundMusic (function) - State setter to store the sound instance
Returns: Promise<void> Audio Configuration:
await Audio.setAudioModeAsync({
  allowsRecordingIOS: false,
  staysActiveInBackground: false,
  playsInSilentModeIOS: true,      // Plays even in iOS silent mode
  shouldDuckAndroid: true,          // Lowers volume for other audio
});
Playback Options:
  • shouldPlay: true - Starts playing immediately
  • isLooping: true - Loops continuously
  • volume: 0.2 - Set to 20% volume
Example:
const [backgroundMusic, setBackgroundMusic] = useState(null);

useEffect(() => {
  setupRouteOne(setBackgroundMusic);
  
  return () => {
    if (backgroundMusic) {
      backgroundMusic.unloadAsync();
    }
  };
}, []);

playIntro()

Plays the intro theme sound effect. Parameters: None Returns: Audio.Sound instance Example:
const introSound = playIntro();

// Clean up after 4 seconds
setTimeout(async () => {
  await introSound.unloadAsync();
}, 4000);

Implementation Details

Audio Playback for Pokémon Cries

The playSound function creates and plays audio asynchronously:
const playSound = async (uri) => {
  try {
    const { sound } = await Audio.Sound.createAsync({ uri });
    await sound.playAsync();
  } catch (error) {
    console.error("Error al reproducir el audio:", error);
  }
};

Background Music Configuration

Background music is configured to:
  • Play even when the device is in silent mode (iOS)
  • Duck (lower volume) when other audio plays (Android)
  • Loop continuously at 20% volume
  • Not stay active in the background

Integration with expo-av

This hook uses the expo-av library’s Audio API, which provides:
  • Cross-platform audio playback (iOS and Android)
  • Audio mode configuration for different playback scenarios
  • Sound instance management and controls
  • Support for both local and remote audio files
For more details, see the expo-av Audio documentation.

Source Code

~/workspace/source/src/hooks/useSound.js
import { Audio } from 'expo-av';

export const useSound = () => {
    const playSound = async (uri) => {
        try {
            const { sound } = await Audio.Sound.createAsync({ uri });
            await sound.playAsync();
        } catch (error) {
            console.error("Error al reproducir el audio:", error);
        }
    };

    async function setupRouteOne(setBackgroundMusic) {
        try {
            await Audio.setAudioModeAsync({
                allowsRecordingIOS: false,
                staysActiveInBackground: false,
                playsInSilentModeIOS: true,
                shouldDuckAndroid: true,
            });

            const { sound } = await Audio.Sound.createAsync(
                require('./../../assets/sounds/route1_loop.mp3'),
                {
                    shouldPlay: true,
                    isLooping: true,
                    volume: 0.2
                }
            );
            setBackgroundMusic(sound);
        } catch (error) {
            console.log("Error cargando música de fondo", error);
        }
    }

    function playIntro() {
        let soundObject = new Audio.Sound();
        soundObject.loadAsync(require('./../../assets/sounds/intro_theme.mp3'));
        soundObject.playAsync();

        return soundObject;
    }

    return { playSound, setupRouteOne, playIntro };
}

Best Practices

  • Always unload sound instances when components unmount to prevent memory leaks
  • Handle errors gracefully with try-catch blocks
  • Use Audio.setAudioModeAsync() to configure playback behavior before playing sounds
  • Consider device silent mode settings when implementing audio features
  • Store sound instances in state for lifecycle management
  • Clean up background music when navigating away from screens