#react-native musicplayer

#react-native musicplayer

Introducción - Introduction

Este código es un buen ejemplo de cómo manejar la reproducción de audio en una aplicación de React Native, incluyendo la navegación entre canciones y el control de la reproducción.

This code is a good example of how to handle audio playback in a React Native application, including navigating between songs and controlling playback.

Código - Code

tracks-data.ts

export const TRACKS = [
  {
    title: 'A Dios le pido',
    artist: 'Juanes',
    albumArtUrl: 'https://e-cdn-images.dzcdn.net/images/cover/33e04e87595d7b24b5bb45ed202ca6b9/500x500-000000-80-0-0.jpg',
    audioUrl:
      'https://cdns-preview-5.dzcdn.net//stream//c-505de2a25dc13d6f1bb5cecfa7b89e33-8.mp3',
  },
  {
    title: 'La Camisa Negra',
    artist: 'Juanes',
    albumArtUrl:
      'https://e-cdn-images.dzcdn.net/images/cover/a443a2c90389167f0f7958106e71c055/500x500-000000-80-0-0.jpg',
    audioUrl:
      'https://cdns-preview-f.dzcdn.net//stream//c-f0f277d1134ceb279f378bcedd14d929-6.mp3',
  },
  {
    title: 'La Vida Es Un Ratico',
    artist: 'Juanes',
    albumArtUrl:
      'https://e-cdn-images.dzcdn.net/images/cover/74b1e208c0a21ae8f9e2dede1ec1fe1d/500x500-000000-80-0-0.jpg',
    audioUrl:
      'https://cdns-preview-4.dzcdn.net//stream//c-4000a50b6fe8b16d07e32a7fa6988a06-9.mp3',
  },
];

Español:

  • export const TRACKS: Esto exporta la constante TRACKS para que pueda ser importada y utilizada en otros archivos de tu proyecto.

  • Cada objeto dentro del array representa una canción.

  • title: El título de la canción.

  • artist: El artista de la canción.

  • albumArtUrl: La URL de la imagen del álbum de la canción. Esta imagen se puede utilizar para mostrar la portada del álbum en la interfaz de usuario de la aplicación.

  • audioUrl: La URL del archivo de audio de la canción. Esta URL se puede utilizar para reproducir la canción.

English

  • export const TRACKS: This exports the TRACKS constant so it can be imported and used in other files in your project.

  • Each object within the array represents a song.

  • title: The title of the song.

  • artist: The artist of the song.

  • albumArtUrl: The URL of the album artwork. This image can be used to display the album cover in the application's user interface.

  • audioUrl: The URL of the audio file. This URL can be used to play the song.

AlbumCover.tsx

import React from 'react';
import { Dimensions, Image, StyleSheet, View } from 'react-native';

const { width } = Dimensions.get('window');

interface AlbumCoverProps {
 albumCover: string;
}

export default function AlbumCover({ albumCover }: AlbumCoverProps) {
 return (
    <View style={styles.container}>
      <Image
        source={{ uri: albumCover }}
        style={styles.image}
        resizeMode="contain"
      />
    </View>
 );
}

const styles = StyleSheet.create({
 container: {
    margin: 10,
    width: width,
    height: 300,
    borderRadius: 5,
    backgroundColor: 'transparent', 
 },
 image: {
    width: '100%',
    height: '100%',
    borderRadius: 5, 
 },
});

Español

Este código define un componente de React Native llamado AlbumCover que muestra una imagen de la portada de un álbum. Utiliza la API de Dimensions para obtener el ancho de la ventana del dispositivo y ajusta el tamaño de la imagen de la portada del álbum en consecuencia.

  • Importaciones: Importa React de la biblioteca de React, y varios componentes y APIs de React Native como Dimensions, Image, StyleSheet, y View.

  • Obtener el ancho de la ventana: Utiliza Dimensions.get('window') para obtener el ancho de la ventana del dispositivo y lo almacena en la constante width.

  • Definición de la interfaz AlbumCoverProps: Define una interfaz para las propiedades que AlbumCover espera recibir. En este caso, solo espera una propiedad albumCover que es una cadena de texto que representa la URL de la imagen de la portada del álbum.

  • Componente AlbumCover: Define el componente AlbumCover que recibe las propiedades definidas en AlbumCoverProps. Dentro del componente, retorna un View que contiene una Image. La imagen utiliza la propiedad albumCover para obtener su fuente y se le asignan estilos definidos en styles.

  • Definición de estilos: Utiliza StyleSheet.create para definir estilos para el contenedor y la imagen. El contenedor tiene un margen, un ancho que corresponde al ancho de la ventana, una altura fija de 300, un borde redondeado y un fondo transparente. La imagen se ajusta para ocupar el 100% del ancho y alto del contenedor, con un borde redondeado.

English

This code defines a React Native component called AlbumCover that displays an album cover image. It uses the Dimensions API to get the window's width of the device and adjusts the size of the album cover image accordingly.

  • Imports: Imports React from the React library, and several components and APIs from React Native such as Dimensions, Image, StyleSheet, and View.

  • Get the window width: Uses Dimensions.get('window') to get the width of the device window and stores it in the constant width.

  • Define the AlbumCoverProps interface: Defines an interface for the props that AlbumCover expects to receive. In this case, it only expects an albumCover prop that is a string representing the URL of the album cover image.

  • AlbumCover component: Defines the AlbumCover component that receives the props defined in AlbumCoverProps. Inside the component, it returns a View that contains an Image. The image uses the albumCover prop to get its source and is assigned styles defined in styles.

  • Styles definition: Uses StyleSheet.create to define styles for the container and the image. The container has a margin, a width that corresponds to the window's width, a fixed height of 300, a rounded border, and a transparent background. The image is adjusted to fill 100% of the container's width and height, with a rounded border.

AlbumDetails.tsx

import { StyleSheet, Text, View } from 'react-native'
import React from 'react'

interface AlbumDetailsProps {
  trackName: string;
  artistName: string;
}

const AlbumDetails = ({trackName, artistName}: AlbumDetailsProps) => {
  return (
    <View style={{justifyContent:'center'}}>
      <Text style={styles.name}>{artistName}</Text>
      <Text style={styles.name}>{trackName}</Text>
    </View>
  )
}

export default AlbumDetails

const styles = StyleSheet.create({
    name: {
        textAlign: 'center',
        fontWeight: 'bold',
        fontSize: 20,
        color: '#DAE0E2'
    }
})

Español

  • Importaciones: Se importan varios componentes de React Native y React.

  • Interfaz de Propiedades: Se define una interfaz AlbumDetailsProps que especifica las propiedades que el componente espera recibir: trackName y artistName.

  • Componente AlbumDetails: Se define un componente funcional que recibe trackName y artistName como props y devuelve un contenedor View con dos componentes Text, uno para el nombre del artista y otro para el nombre de la canción. Estos componentes Text se centran verticalmente dentro del contenedor.

  • Estilos: Se define un objeto styles que contiene un estilo name para los componentes Text. Este estilo establece el texto en el centro, lo pone en negrita, define el tamaño de la fuente y el color.

English

  • Imports: Several components from React Native and React are imported.

  • Props Interface: An interface AlbumDetailsProps is defined specifying the properties the component expects to receive: trackName and artistName.

  • AlbumDetails Component: A functional component is defined that receives trackName and artistName as props and returns a View container with two Text components, one for the artist's name and one for the song's name. These Text components are centered vertically within the container.

  • Styles: A styles object is defined containing a name style for the Text components. This style centers the text, makes it bold, sets the font size, and colors it.

Controls.tsx

import React from 'react';
import { StyleSheet, TouchableOpacity, View } from 'react-native';
import AntDesign from 'react-native-vector-icons/AntDesign';

interface ControlsProps {
  tooglePlayPauseBtn: () => void; // Indica que tooglePlayPauseBtn es una función que no devuelve nada
  pause: boolean; // Indica que pause es un valor booleano
  playNextSong:() => void;
  playPrevSong:() => void;
}

const Controls: React.FC<ControlsProps> = ({ tooglePlayPauseBtn, pause, playNextSong, playPrevSong }) => {
  return (
    <View style={styles.container}>
      {/* prevbtn */}
      <TouchableOpacity onPress={playPrevSong}>
        <AntDesign name='banckward' size={32} color="#F9DDA4"/>
      </TouchableOpacity>

      {/* play/pause btn */}
      <TouchableOpacity style={styles.playPauseBtn} onPress={tooglePlayPauseBtn}>
        <AntDesign name={pause ? 'playcircleo' : 'pausecircleo'} size={32} color="#30336B"/>
      </TouchableOpacity>

      {/* nextbtn */}
      <TouchableOpacity onPress={playNextSong}>
        <AntDesign name='forward' size={32} color="#F9DDA4"/>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop:   20
  },
  playPauseBtn: {
    width:   120,
    height:   120,
    backgroundColor: '#fff',
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius:   100,
    borderWidth:   20,
    borderColor: '#30336B',
    margin:   20
  }
});

export default Controls;

Español

  • Importaciones: Se importan varios componentes de React Native y React, así como el conjunto de iconos AntDesign de react-native-vector-icons.

  • Interfaz de Propiedades: Se define una interfaz ControlsProps que especifica las propiedades que el componente espera recibir: tooglePlayPauseBtn (una función para alternar entre reproducir y pausar), pause (un valor booleano que indica si la reproducción está pausada), y dos funciones para reproducir la canción siguiente o anterior.

  • Componente Controls: Se define un componente funcional que recibe las propiedades definidas en ControlsProps. Dentro del componente, se renderiza un contenedor View que contiene tres botones controlados por TouchableOpacity para reproducir la canción anterior, pausar/reproducir la canción actual, y reproducir la siguiente canción. Los botones utilizan iconos de AntDesign para representar su función.

  • Estilos: Se define un objeto styles que contiene estilos para el contenedor principal y el botón de pausar/reproducir.

English

  • Imports: Several components from React Native and React are imported, as well as the AntDesign icon set from react-native-vector-icons.

  • Props Interface: An interface ControlsProps is defined specifying the properties the component expects to receive: tooglePlayPauseBtn (a function to toggle between play and pause), pause (a boolean value indicating if playback is paused), and two functions to play the next or previous song.

  • Controls Component: A functional component is defined that receives the properties defined in ControlsProps. Inside the component, a View container is rendered that contains three buttons controlled by TouchableOpacity for playing the previous song, pausing/playing the current song, and playing the next song. The buttons use AntDesign icons to represent their function.

  • Styles: A styles object is defined containing styles for the main container and the play/pause button.

App.tsx

import React, { useState } from 'react';
import { StatusBar, StyleSheet, View } from 'react-native';
import Video from 'react-native-video';
import AlbumCover from './src/components/AlbumCover';
import AlbumDetails from './src/components/AlbumDetails';
import Controls from './src/components/Controls';
import { TRACKS } from './src/components/tracks-data';

const App = () => {
 const [selectedTrack, setSelectedTrack] = useState(0);
 const [pause, setPause] = useState(false);

 const currentTrack = TRACKS[selectedTrack];

 function togglePlayPauseBtn() {
    setPause(!pause);
 }

 function playNextSong() {
    if (selectedTrack === TRACKS.length - 1) {
      setSelectedTrack(0);
    } else {
      setSelectedTrack(selectedTrack + 1);
    }
 }

 function playPrevSong() {
    if (selectedTrack === 0) {
      setSelectedTrack(TRACKS.length - 1);
    } else {
      setSelectedTrack(selectedTrack - 1);
    }
 }

 function handleVideoEnd() {
    playNextSong();
 }

 return (
    <>
      <StatusBar hidden />
      <View style={styles.container}>
        <AlbumCover albumCover={currentTrack.albumArtUrl} />
        <AlbumDetails trackName={currentTrack.title} artistName={currentTrack.artist} />
        <Controls tooglePlayPauseBtn={togglePlayPauseBtn} pause={pause} playNextSong={playNextSong} playPrevSong={playPrevSong} />
        <Video 
          source={{uri: currentTrack.audioUrl}} 
          audioOnly={true} 
          paused={pause} 
          repeat={false} 
          onEnd={handleVideoEnd} 
        />
      </View>
    </>
 );
};

const styles = StyleSheet.create({
 container: {
    flex: 1,
    backgroundColor: '#2B2B52',
 },
});

export default App;

Español

  • Importaciones: Se importan varios componentes y funciones de React Native y otras bibliotecas. useState se usa para gestionar el estado local del componente.

  • Estado inicial: Se inicializan dos estados: selectedTrack para almacenar el índice de la canción actualmente seleccionada y pause para controlar si el video está en pausa o no.

  • Obtención de la canción actual: Se obtiene la canción actual basada en el índice almacenado en selectedTrack.

  • Funciones de control: Se definen varias funciones para controlar la reproducción de las canciones. togglePlayPauseBtn cambia el estado de pause. playNextSong y playPrevSong cambian la canción actual a la siguiente o anterior, respetando el final y el principio de la lista de canciones.

  • Manejo del fin de la reproducción: La función handleVideoEnd se llama cuando la canción termina, y en este caso, simplemente reproduce la siguiente canción.

  • Renderizado: Se renderiza la interfaz del usuario, incluyendo la portada del álbum, los detalles de la canción, los controles de reproducción y el componente Video para reproducir la canción actual.

  • Estilos: Se definen estilos para el contenedor principal de la aplicación.

English

  • Imports: Various components and functions from React Native and other libraries are imported. useState is used to manage the local state of the component.

  • Initial State: Two states are initialized: selectedTrack to store the index of the currently selected song and pause to control whether the video is paused or not.

  • Getting the Current Song: The current song is obtained based on the index stored in selectedTrack.

  • Control Functions: Several functions are defined to control the playback of songs. togglePlayPauseBtn toggles the pause state. playNextSong and playPrevSong change the current song to the next or previous one, respecting the end and the beginning of the song list.

  • Handling End of Playback: The handleVideoEnd function is called when the song ends, and in this case, it simply plays the next song.

  • Rendering: The user interface is rendered, including the album cover, song details, playback controls, and the Video component to play the current song.

  • Styles: Styles are defined for the main container of the application.

npm packages

react-native-vector-icons - https://www.npmjs.com/package/react-native-vector-icons

react-native-video - https://www.npmjs.com/package/react-native-video