繁体   English   中英

如何在我的反应组件中快进音频?

[英]How do I fast-forward the audio in my react component?

我有一个显示音频播放器的反应组件。 我需要实现一个功能,您可以在音频 15 秒内来回 go。 我有一个名为 skip 的 function 可以执行此操作,但它只会更新时间并且不会移动音轨。 我做错了什么? 这是我的音频播放器的图像

在此处输入图像描述

import React, { useState, useEffect, useRef } from "react";
import "./AudioPlayer.css";
import Navbar from "../../components/Navbar/Navbar";
import { useParams } from "react-router-dom";
import axios from "axios";
import Slider from "../../components/Slider/Slider";
import ControlPanel from "../../components/Controls/ControlPanel";
import * as RiIcons from "react-icons/ri";

function AudioPlayer() {
    const [episodeData, setEpisodeData] = useState([]);
    const [percentage, setPercentage] = useState();
    const [isPlaying, setIsPlaying] = useState(false);
    const [duration, setDuration] = useState(0);
    const [currentTime, setCurrentTime] = useState();
    const [speed, setSpeed] = useState(1);

    const audioRef = useRef();

    const onChange = (e) => {
        const audio = audioRef.current;
        audio.currentTime = (audio.duration / 100) * e.target.value;
        setPercentage(e.target.value);
    };

    const play = () => {
        const audio = audioRef.current;
        // audio.playbackRate = speed;
        audio.volume = 0.1;

        if (!isPlaying) {
            setIsPlaying(true);
            audio.play();
        }

        if (isPlaying) {
            setIsPlaying(false);
            audio.pause();
        }
    };

    const getCurrDuration = (e) => {
        const percent = (
            (e.currentTarget.currentTime / e.currentTarget.duration) *
            100
        ).toFixed(2);

        const time = e.currentTarget.currentTime;

        setPercentage(+percent);
        setCurrentTime(time.toFixed(2));
    };

    const changeSpeed = () => {
        if (speed >= 2) {
            setSpeed(0.5);
        } else setSpeed(speed + 0.5);
    };

    const skip = (time) => {
        const audio = audioRef.current;

        if (time == "back") {
            console.log("15");
            setCurrentTime(audio.currentTime - 15);
        } else if (time == "fwd") {
            console.log("15");
            setCurrentTime(audio.currentTime + 15);
        }
    };

    const { id } = useParams();

    const headers = { jwt_token: localStorage.token };

    useEffect(() => {
        axios
            .get(`/api/get/episodes/${id}`, { headers })
            .then((res) => setEpisodeData(res.data));
    }, []);

    useEffect(() => {
        const audio = audioRef.current;
        audio.playbackRate = speed;
    }, [speed]);

    return (
        <div>
            <Navbar />
            <div>
                <div style={{ width: "60%", margin: "0 auto", paddingTop: "10rem" }}>
                    <div className="app-container">
                        <h3 style={{ color: "#fff" }}>{episodeData.podcast_title}</h3>
                        <h3 style={{ color: "#fff" }}>{episodeData.episode_title}</h3>

                        <Slider percentage={percentage} onChange={onChange} />
                        <audio
                            ref={audioRef}
                            onTimeUpdate={getCurrDuration}
                            onLoadedData={(e) => {
                                setDuration(e.currentTarget.duration.toFixed(2));
                            }}
                            src={episodeData.episode_audio}
                        ></audio>
                        <ControlPanel
                            play={play}
                            isPlaying={isPlaying}
                            duration={duration}
                            currentTime={currentTime}
                        />
                        <button className="speed-button" onClick={() => changeSpeed()}>
                            {speed}x
                        </button>
                        <button onClick={() => skip("back")}>
                            BACK 15 SECONDS
                            <RiIcons.RiArrowGoBackLine color={"white"} size={16} />
                        </button>
                        <button onClick={() => skip("fwd")}>
                            <RiIcons.RiArrowGoForwardLine color={"white"} size={16} />
                            FORWARD 15 SECONDS
                        </button>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default AudioPlayer;

您的代码的问题是,您正在尝试更改组件的 state,因为您应该更改音频播放器的当前时间

currentTime 属性设置或返回音频/视频播放的当前 position(以秒为单位)。

设置该属性时,播放会跳转到指定的position。

const skip = (time) => {
  const audio = audioRef.current;

  if (time == 'back') {
    // changes
    audio.currentTime = audio.currentTime - 15;
  } else if (time == 'fwd') {
    // changes
    audio.currentTime = audio.currentTime + 15;
  }
};

通过使用 ref 更改音频播放器的当前时间,音频播放器会跳转到指定的 position,因此您的 onchange function 也会被调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM