Skip to content

Latest commit

 

History

History
executable file
·
121 lines (105 loc) · 2.92 KB

React Hook实战-封装Audio.md

File metadata and controls

executable file
·
121 lines (105 loc) · 2.92 KB

React Hook实战-封装Audio

在线效果预览

实现

const useMediaPlay = (mediaRef) => {
  const [playing, setPlaying] = useState(false);
  useEffect(() => {
    if (!mediaRef.current) return;
    const audio = mediaRef.current;
    audio.addEventListener("playing", () => {
      setPlaying(true);
    });
    audio.addEventListener("pause", () => {
      setPlaying(false);
    });
  }, []);

  const play = () => {
    mediaRef.current && mediaRef.current.play();
  };

  const pause = () => {
    mediaRef.current && mediaRef.current.pause();
  };
  return {
    playing,
    play,
    pause,
  };
};

// 播放时间控制
const useMediaDuraion = (mediaRef) => {
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0.1);
  useEffect(() => {
    if (!mediaRef.current) return;
    const audio = mediaRef.current;
    audio.addEventListener("durationchange", () => {
      setDuration(audio.duration);
    });
    audio.addEventListener("timeupdate", () => {
      setCurrentTime(audio.currentTime);
    });
  }, []);
  const updateCurrentTime = (value) => {
    mediaRef.current.currentTime = value;
  };
  return {
    currentTime,
    updateCurrentTime,
    duration,
  };
};

// 声音操作控制
const useMediaVolume = (mediaRef) => {
  // volume的范围: [0,1]
  const [volume, setVolume] = useState(0.5);
  useEffect(() => {
    if (!mediaRef.current) return;
    const audio = mediaRef.current;
    audio.addEventListener("volumechange", () => {
      setVolume(mediaRef.current.volume);
    });
  }, []);
  const updateVolume = (value) => {
    mediaRef.current.volume = value;
  };
  return {
    volume,
    updateVolume,
  };
};

// 导出给外部使用的useMedia
const useMediaControl = (item) => {
  const mediaRef = useRef(null);

  useLayoutEffect(() => {
    if (!mediaRef.current) {
      mediaRef.current = document.createElement("audio");
      mediaRef.current.src = item.src;
      mediaRef.current.preload = "auto";
    }
  });

  const { playing, play, pause } = useMediaPlay(mediaRef);

  const { currentTime, updateCurrentTime, duration } =
    useMediaDuraion(mediaRef);

  const { volume, updateVolume } = useMediaVolume(mediaRef);

  return {
    state: {
      playing,
      currentTime,
      duration,
      volume,
    },
    action: {
      play,
      pause,
      updateCurrentTime,
      updateVolume,
    },
  };
};

完整代码见此处

参考