如何自动播放下一首歌曲 onClick on a btn

How to autoplay the next song onClick on a btn

我前面有个问题。 我正在尝试创建一个音乐播放器。 但是现在,我在单击下一个按钮时加载下一首音乐时遇到了问题。 state 和 render 中都替换了新的数据,但是点击按钮后音乐并没有自己播放。 我想我应该使用音频或视频元素的 load () 函数来重新加载媒体,但它不起作用。 我把我的代码给你,这样你就可以看看。它当然不完美,我知道我可以改进我的代码的某些点。

我想做的是下一个功能何时启动。我选择当前歌曲,然后为新信息添加 +1,然后我用新信息更新状态。 当新信息处于状态时,我暂停音乐,然后加载新歌曲,并在我启动播放功能后检查他是否需要暂停或播放音乐。 如果有人可以指导我如何解决问题,那就太好了!

非常感谢!

import React, { Component } from 'react'
import data from '../data/list-music.json'
export default class audioPlayer extends Component {
    constructor(props) {
        super(props);

        this.audio = React.createRef();

        this.state = {
            musicList: data,
            playing: false,
            currentMusic: 0,
            nextMusic: 1,
            repeat: false,
            volume: 0.1,
            currentTitle: data[0].name,
            currentImage: data[0].img,
            currentSongSrc: data[0].src
        };
    }

    playing = (e) => {
        this.state.playing ? this.pause() : this.play();
    }
    play() {
        const audio = this.audio.current
        this.setState({ playing: true })
        audio.play()
        audio.volume = this.state.volume
    }
    pause() {
        const audio = this.audio.current
        this.setState({ playing: false })
        audio.pause()
    }

    // GET THE PREVIOUS MUSIC
    previous = (e) => {

        let currentSongPlaying = this.state.currentMusic
        let nextSongPlaying = this.state.nextMusic

        currentSongPlaying = currentSongPlaying - 1
        nextSongPlaying = currentSongPlaying + 1

        this.setState({
            currentMusic: currentSongPlaying,
            nextMusic: nextSongPlaying,
            currentTitle: data[currentSongPlaying].name,
            currentImage: data[currentSongPlaying].img,
            currentSongSrc: data[currentSongPlaying].src
        })
    }
    // GET THE NEXT MUSIC
    next = (e) => {
        let currentSongPlaying = this.state.currentMusic
        let nextSongPlaying = this.state.nextMusic

        currentSongPlaying = currentSongPlaying + 1
        nextSongPlaying = currentSongPlaying + 1

        this.setState({
            currentMusic: currentSongPlaying,
            nextMusic: nextSongPlaying,
            currentTitle: data[currentSongPlaying].name,
            currentImage: data[currentSongPlaying].img,
            currentSongSrc: data[currentSongPlaying].src
        })
        const audio = this.audio.current
        this.pause()
        audio.load()
        this.playing()
    }

    render() {
        const isPlaying = this.state.playing
        const poster = this.state.currentImage
        const titre = this.state.currentTitle
        const song = this.state.currentSongSrc
        const music = require("../music/" + song + ".mp3")
        return (
            <div>
                <h1>Audio Player</h1>
                <audio id="main-audio" src={music.default} ref={this.audio} ></audio>
                <p>{titre}</p>
                <button onClick={this.previous}>
                    previous
                </button>
                <button onClick={this.playing}>
                    {isPlaying ? 'Pause' : 'Play'}
                </button>
                <button onClick={this.next}>
                    next
                </button>
            </div>
        )
    }
}

当您将状态更新加入队列然后尝试调用 pause、加载音频和 play 时,您使用的是陈旧状态。该组件还没有重新呈现 this.audio ref 也已经更新。

状态更新排队后,您需要暂停当前播放的曲目并使用 componentDidUpdate 生命周期挂钩开始下一个曲目。

componentDidUpdate(prevProps, prevState) {
  if (prevState.currentMusic !== this.state.currentMusic) {
    this.audio.current.load();
    this.play();
  }
}

next = (e) => {
  this.setState(prevState => {
    const { currentMusic, nextMusic } = prevState;

    return {
      currentMusic: currentMusic + 1,
      nextMusic: nextMusic + 1,
    }
  });
  this.pause();
}

您需要对 prev 应用类似的修复。事实上,由于这两个函数基本相同,唯一的区别是 incrementing/decrementing 和 current/next 值,您可以将它们组合成一个柯里化函数并在范围内关闭 incrementing/decrementing 值。

incrementTrack = (val) => (e) => {
  this.setState(prevState => {
    const { currentMusic, nextMusic } = prevState;

    return {
      currentMusic: currentMusic + val,
      nextMusic: nextMusic + val,
    }
  });
  this.pause();
}

标题、图像和歌曲来源都被视为“派生”状态,这意味着从 实际 currentMusic 状态和 data 您可以推导出这个“状态”。

render() {
  const { currentMusic, playing: isPlaying } = this.state
  const {
    name: title,
    img: poster,
    src: song,
  } = data[currentMusic];

  const music = require("../music/" + song + ".mp3");

  return (
    <div>
      <h1>Audio Player</h1>
      <audio id="main-audio" src={music.default} ref={this.audio} ></audio>
      <p>{title}</p>
      <button onClick={this.incrementTrack(-1)}>
        previous
      </button>
      <button onClick={this.playing}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <button onClick={this.incrementTrack(1)}>
        next
      </button>
    </div>
  );
}