Cours React Native · Module 6: Photos, appareil photo et son

expo-av - Audio et vidéo

2 min de lecture ·
Dans cette leçon5

Lis de l'audio et de la vidéo dans ton application !

Installation

npx expo install expo-av

Lecture vidéo

import { Video, ResizeMode } from 'expo-av';
import { useState, useRef } from 'react';

function VideoPlayer() {
  const videoRef = useRef<Video>(null);
  const [status, setStatus] = useState<any>({});

  return (
    <View style={styles.container}>
      <Video
        ref={videoRef}
        style={styles.video}
        source={{ uri: 'https://example.com/video.mp4' }}
        useNativeControls
        resizeMode={ResizeMode.CONTAIN}
        isLooping
        onPlaybackStatusUpdate={(status) => setStatus(() => status)}
      />

      <View style={styles.controls}>
        <Pressable
          onPress={() =>
            status.isPlaying
              ? videoRef.current?.pauseAsync()
              : videoRef.current?.playAsync()
          }
        >
          <Ionicons
            name={status.isPlaying ? 'pause' : 'play'}
            size={32}
          />
        </Pressable>
      </View>
    </View>
  );
}

Lecture audio

import { Audio } from 'expo-av';

function AudioPlayer() {
  const [sound, setSound] = useState<Audio.Sound>();
  const [isPlaying, setIsPlaying] = useState(false);

  const playSound = async () => {
    const { sound } = await Audio.Sound.createAsync(
      require('@/assets/audio/ocean.mp3')
    );
    setSound(sound);
    await sound.playAsync();
    setIsPlaying(true);
  };

  const pauseSound = async () => {
    if (sound) {
      await sound.pauseAsync();
      setIsPlaying(false);
    }
  };

  // Nettoyage
  useEffect(() => {
    return sound
      ? () => {
          sound.unloadAsync();
        }
      : undefined;
  }, [sound]);

  return (
    <Pressable onPress={isPlaying ? pauseSound : playSound}>
      <Ionicons name={isPlaying ? 'pause' : 'play'} size={48} />
    </Pressable>
  );
}

Audio en arrière-plan

import { Audio } from 'expo-av';

async function setupAudio() {
  await Audio.setAudioModeAsync({
    playsInSilentModeIOS: true,
    staysActiveInBackground: true,
    shouldDuckAndroid: true,
  });
}

Enregistrement audio

import { Audio } from 'expo-av';

function AudioRecorder() {
  const [recording, setRecording] = useState<Audio.Recording>();
  const [recordingUri, setRecordingUri] = useState<string>();

  const startRecording = async () => {
    try {
      const permission = await Audio.requestPermissionsAsync();
      if (!permission.granted) return;

      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
      });

      const { recording } = await Audio.Recording.createAsync(
        Audio.RecordingOptionsPresets.HIGH_QUALITY
      );

      setRecording(recording);
    } catch (error) {
      console.error('Erreur d\'enregistrement :', error);
    }
  };

  const stopRecording = async () => {
    if (!recording) return;

    await recording.stopAndUnloadAsync();
    const uri = recording.getURI();
    setRecordingUri(uri ?? undefined);
    setRecording(undefined);
  };

  return (
    <View>
      <Pressable
        onPress={recording ? stopRecording : startRecording}
        style={[styles.recordButton, recording && styles.recording]}
      >
        <Ionicons name={recording ? 'stop' : 'mic'} size={32} color="white" />
      </Pressable>

      {recordingUri && <Text>Enregistré : {recordingUri}</Text>}
    </View>
  );
}

expo-av répond à tous tes besoins audio/vidéo !

Code de cette leçon : App.tsx
import React, { useState, useEffect } from 'react';
import { View, Text, Pressable, StyleSheet } from 'react-native';
import { Audio } from 'expo-av';

export default function App() {
  const [sound, setSound] = useState<Audio.Sound>();
  const [isPlaying, setIsPlaying] = useState(false);

  const playSound = async () => {
    // TODO : crée un son avec Audio.Sound.createAsync(...)
    //   - transmets { uri: 'https://example.com/ocean.mp3' } comme source
    //   - déstructure le résultat : const { sound } = await Audio.Sound.createAsync(...)
    //   - stocke-le : setSound(sound)
    //   - démarre la lecture : await sound.playAsync()
    //   - définis setIsPlaying(true)

  };

  const pauseSound = async () => {
    if (sound) {
      await sound.pauseAsync();
      setIsPlaying(false);
    }
  };

  // Libère la ressource audio au démontage
  useEffect(() => {
    return sound ? () => { sound.unloadAsync(); } : undefined;
  }, [sound]);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Sons de l'Atlantide</Text>
      <Pressable
        style={styles.button}
        onPress={isPlaying ? pauseSound : playSound}
      >
        <Text style={styles.buttonText}>{isPlaying ? 'Pause' : 'Lecture'}</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#1a5276' },
  title: { color: '#aed6f1', fontSize: 20, marginBottom: 24 },
  button: { backgroundColor: '#2980b9', paddingVertical: 14, paddingHorizontal: 40, borderRadius: 8 },
  buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
});

Entrées de la documentation utilisées dans cette leçon

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelle prop active les contrôles natifs dans le composant Video ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Clique sur les éléments pour créer un son :

  • Éditeur de code

    Complète le code d'Audio.Sound avec play/pause.

Articles utiles