Home > Software engineering >  React.js Music-Player: How can I play audio when list element is clicked?
React.js Music-Player: How can I play audio when list element is clicked?

Time:04-27

Good afternoon all,

I am a new programmer and I recently started following a music-player tutorial, and am experiencing a couple of issues with it.

Project Overview:

As previously described, it is a music-player project made with create-react-app. The objective is to click the image of the song of your choosing, and for the song to be played for you.

The songs are saved as mp3’s in a folder named music. The music folder is located in the src directory. Each song is assigned to its given song image (as you’ll see on the code I provided below). Then the songs/images are wrapped in an <ol> list element.

The Problem:

I am having trouble with playing the audio when the image is clicked. I’ve integrated a lot of the advice I’ve recieved from different users. Though i’m grateful for the result, which is that the code compiles (no error messages), I’m still experiencing the same issue, and that is that the audio doesn’t play when clicked.

So to clarify, How can I make it so that when I click the list element, It will play the assigned audio? Please correct my code and provide an example of the solution using the code I’ve provided below. Due to my novice skills, I am not familiar with any complex terms.

The Code:

Turkish.js (the music-player file):

import React, { Component,audio,useRef } from 'react';

import turk1 from "../music/turk1.mp3";
import turk2 from "../music/turk2.mp3"
import turk3 from "../music/turk3.mp3"
import turk4 from "../music/turk4.mp3"

const data = [
    { imgSrc: 'turk1.png', audioSrc: turk1 },
    { imgSrc: 'turk2.png', audioSrc: turk2 },
    { imgSrc: 'turk3.png', audioSrc: turk3 },
    { imgSrc: 'turk4.png', audioSrc: turk4 },
  ];

  export default class Turkish extends Component {
    render() {
      return (
        <div>
          <ol>
            {data.map(({ imgSrc, audioSrc }) => (
              <MediaComponent imgSrc={imgSrc} audioSrc={audioSrc} />
            ))}
          </ol>
        </div>
      );
    }
  }
  
  const MediaComponent = ({ imgSrc, audioSrc }) => {
    const audioRef = useRef(null);
    const toggleAudio = () =>
      audio.ref.current.paused
        ? audioRef.current.play()
        : audioRef.current.pause();
    return (
      <li>
        <img src={imgSrc} onClick={toggleAudio}/>
        <audio ref={audioRef} src={audioSrc} />
      </li>
    );
  };

Package.json:


{
  "name": "spotifly",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^12.1.5",
    "@testing-library/user-event": "^13.5.0",
    "bootstrap": "^5.1.3",
    "navbar": "^2.1.0",
    "react": "^18.0.0",
    "react-audio-player": "^0.17.0",
    "react-bootstrap": "^2.2.3",
    "react-bootstrap-icons": "^1.8.1",
    "react-dom": "^18.0.0",
    "react-is": "^18.0.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Picture of the Music folder:

enter image description here

When I click on the song file, it tells me this:

enter image description here

I really appreciate your time & effort, let me know what you think!

Best,

-Zpo

CodePudding user response:

Remove 'audio' from import React, { Component,audio,useRef } from 'react';

const MediaComponent = ({ imgSrc, audioSrc }) => {
  const audioRef = useRef(null);
  const toggleAudio = () =>
    audioRef.current === null
      ? console.log("Audio component is not loaded yet.")
      : audioRef.current.paused
      ? audioRef.current.play()
      : audioRef.current.pause();
  return (
    <li>
      <img src={imgSrc} onClick={toggleAudio} />
      <audio ref={audioRef} src={audioSrc} />
    </li>
  );
};

I can suggest something too. It is up to you.

const AudioPlayer = ({ imgSrc, audioSrc }) => {
  const [status, setStatus] = useState({
    isPlaying: false,
    isLoop: false,
    isLoaded: false,
    error: false,
    ...others,
  });
  const audioRef = useRef(null);

  const toggleAudio = () =>
    status.isLoaded
      ? status.isPlaying
        ? audioRef.current.pause()
        : audioRef.current.play()
      : console.log("Audio has not loaded yet.");

  return (
    <li>
      <img src={imgSrc} onClick={toggleAudio} />
      <audio
        ref={audioRef}
        src={audioSrc}
        onl oad={() => setStatus({ ...status, isLoaded: true })}
        onPlay={() => setStatus({ ...status, isPlaying: true })}
        onPause={() => setStatus({ ...status, isPlaying: false })}
        one rror={() => setStatus({ ...status, error: true })}
      />
    </li>
  );
};
  • Related