123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import React from "react";
- import PropTypes from "prop-types";
- import { PauseOutlined, LoadingOutlined } from "@ant-design/icons";
- import { Slider } from "antd";
- import IconFont from "@components/comment/common/ScheduleIconFont";
- import dayjs from "@components/comment/utils/dayjsImport";
- import styles from "./AudioPlayer.less";
-
- interface AudioPlayerProps {
- src: string;
- }
- interface AudioPlayerState {
- duration: number;
- currentDuration: number;
- isPlaying: boolean;
- isLoading: boolean;
- }
-
- class AudioPlayer extends React.Component<AudioPlayerProps, AudioPlayerState> {
- player: any;
- constructor(props: AudioPlayerProps) {
- super(props);
- this.state = {
- duration: 0,
- currentDuration: 0,
- isPlaying: false,
- isLoading: false,
- };
- }
-
- componentDidMount() {
- if (this.player) {
- const { src } = this.props;
- this.player.oncanplay = (event: any) =>
- this.setState({ duration: event.target.duration });
- this.player.onended = () =>
- this.setState({ isPlaying: false, currentDuration: 0 });
- this.player.onpause = () =>
- this.setState({ isPlaying: false, isLoading: false });
- this.player.onplay = () =>
- this.setState({ isPlaying: false, isLoading: true });
- this.player.onplaying = () =>
- this.setState({ isPlaying: true, isLoading: false });
- this.player.ontimeupdate = (event: any) =>
- this.setState({ currentDuration: event.target.currentTime });
- this.player.src = src;
- }
- }
-
- componentDidUpdate(prevProps: AudioPlayerProps) {
- if (this.props.src !== prevProps.src) {
- this.player.oncanplay = (event: any) =>
- this.setState({ duration: event.target.duration });
- this.player.onended = () =>
- this.setState({ isPlaying: false, currentDuration: 0 });
- this.player.onpause = () =>
- this.setState({ isPlaying: false, isLoading: false });
- this.player.onplay = () =>
- this.setState({ isPlaying: false, isLoading: true });
- this.player.onplaying = () =>
- this.setState({ isPlaying: true, isLoading: false });
- this.player.ontimeupdate = (event: any) =>
- this.setState({ currentDuration: event.target.currentTime });
- this.player.src = this.props.src;
- }
- }
- clickPlayOrPause(isPlaying: boolean) {
- if (!this.player) {
- return;
- }
- if (isPlaying) {
- this.player.pause();
- } else {
- // 如果是播放,先暂停其他的播放
- const playerList = document.getElementsByTagName("audio");
- if (playerList) {
- Array.from(playerList).forEach((player) => {
- if (!player.paused) {
- player.pause();
- }
- });
- }
- this.player.play();
- }
- }
-
- getPlayIcon() {
- const { isPlaying, isLoading } = this.state;
- let playIconElem;
-
- if (isLoading) {
- playIconElem = (
- <LoadingOutlined />
- // <img className="icon-loading" src={iconLoading} alt="iconLoading" />
- );
- } else if (isPlaying) {
- playIconElem = <PauseOutlined />;
- } else {
- playIconElem = <IconFont type="schedule-icon_image_audio" />;
- }
- return playIconElem;
- }
-
- render() {
- const { currentDuration, isPlaying, duration } = this.state;
- return (
- <div className={styles.wrapper}>
- {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
- <audio
- ref={(ref) => {
- this.player = ref;
- }}
- style={{ display: "none" }}
- />
- <span
- className={styles.iconWrapper}
- onClick={() => {
- this.clickPlayOrPause(isPlaying);
- }}
- >
- {this.getPlayIcon()}
- </span>
- <Slider
- step={0.001}
- className={styles.audioSlider}
- tooltipVisible={false}
- value={currentDuration}
- max={duration}
- onChange={(value: any) => {
- if (this.player) {
- this.player.currentTime = value;
- }
- }}
- />
- <span className={styles.timeText}>
- {dayjs
- .utc(dayjs.duration(currentDuration, "seconds").asMilliseconds())
- .format("mm:ss")}
- /
- {dayjs
- .utc(dayjs.duration(duration, "seconds").asMilliseconds())
- .format("mm:ss")}
- </span>
- </div>
- );
- }
- }
-
- export default AudioPlayer;
|