diff --git a/packages/app/src/components/EmbbededMediaPlayer/index.jsx b/packages/app/src/components/EmbbededMediaPlayer/index.jsx index a9732948..43df5f9e 100755 --- a/packages/app/src/components/EmbbededMediaPlayer/index.jsx +++ b/packages/app/src/components/EmbbededMediaPlayer/index.jsx @@ -1,12 +1,12 @@ import React from "react" import * as antd from "antd" +import Slider from "@mui/material/Slider" +import classnames from "classnames" -import { Icons } from "components/Icons" +import { Icons, createIconRender } from "components/Icons" import "./index.less" -// FIXME: JS events are not working properly, the methods cause a memory leak -// FIXME: Use a better way to preload audios // TODO: Check AUDIO quality and show a quality indicator // TODO: Add close button // TODO: Add repeat & shuffle mode @@ -31,14 +31,33 @@ const AudioVolume = (props) => { } -const PlayerStatus = React.memo((props) => { - const [playing, setPlaying] = React.useState(false) - const [time, setTime] = React.useState("00:00") - const [duration, setDuration] = React.useState("00:00") - const [progressBar, setProgressBar] = React.useState(0) +class SeekBar extends React.Component { + state = { + timeText: "00:00", + durationText: "00:00", + sliderTime: 0, + sliderLock: false, + } - const updateDuration = () => { - const audioDuration = app.AudioPlayer.currentAudio.instance.duration() + handleSeek = (value) => { + if (value > 0) { + // calculate the duration of the audio + const duration = app.cores.player.duration() + + // calculate the seek of the audio + const seek = (value / 100) * duration + + app.cores.player.seek(seek) + } else { + app.cores.player.seek(0) + } + } + + calculateDuration = () => { + // get current audio duration + const audioDuration = app.cores.player.duration() + + console.log(`Audio duration: ${audioDuration}`) // convert duration to minutes and seconds const minutes = Math.floor(audioDuration / 60) @@ -53,12 +72,14 @@ const PlayerStatus = React.memo((props) => { const secondsString = seconds < 10 ? `0${seconds}` : seconds // set duration - setDuration(`${minutesString}:${secondsString}`) + this.setState({ + durationText: `${minutesString}:${secondsString}` + }) } - const updateTimer = () => { - // get audio seek - const seek = app.AudioPlayer.currentAudio.instance.seek() + calculateTime = () => { + // get current audio seek + const seek = app.cores.player.seek() // convert seek to minutes and seconds const minutes = Math.floor(seek / 60) @@ -73,272 +94,360 @@ const PlayerStatus = React.memo((props) => { const secondsString = seconds < 10 ? `0${seconds}` : seconds // set time - setTime(`${minutesString}:${secondsString}`) + this.setState({ + timeText: `${minutesString}:${secondsString}` + }) } - const updateProgressBar = () => { - const seek = app.AudioPlayer.currentAudio.instance.seek() - const duration = app.AudioPlayer.currentAudio.instance.duration() + updateProgressBar = () => { + if (this.state.sliderLock) { + return + } + + const seek = app.cores.player.seek() + const duration = app.cores.player.duration() const percent = (seek / duration) * 100 - setProgressBar(percent) + this.setState({ + sliderTime: percent + }) } - const onUpdateSeek = (value) => { - // calculate the duration of the audio - const duration = app.AudioPlayer.currentAudio.instance.duration() - - // calculate the seek of the audio - const seek = (value / 100) * duration - - // update the progress bar - setProgressBar(value) - - // seek to the new value - app.AudioPlayer.currentAudio.instance.seek(seek) + updateAll = () => { + this.calculateTime() + this.updateProgressBar() } - const tooltipFormatter = (value) => { - if (!app.AudioPlayer.currentAudio) { - return "00:00" - } + events = { + "player.status.update": (status) => { + console.log(`Player status updated: ${status}`) - const duration = app.AudioPlayer.currentAudio.instance.duration() + switch (status) { + case "stopped": + this.setState({ + timeText: "00:00", + durationText: "00:00", + sliderTime: 0, + }) - const seek = (value / 100) * duration + break + case "playing": + this.updateAll() + this.calculateDuration() - // convert seek to minutes and seconds - const minutes = Math.floor(seek / 60) - - // add leading zero if minutes is less than 10 - const minutesString = minutes < 10 ? `0${minutes}` : minutes - - // get seconds - const seconds = Math.floor(seek - minutes * 60) - - // add leading zero if seconds is less than 10 - const secondsString = seconds < 10 ? `0${seconds}` : seconds - - return `${minutesString}:${secondsString}` - } - - // create a interval when audio is playing, and destroy it when audio is paused - React.useEffect(() => { - const interval = setInterval(() => { - if (app.AudioPlayer.currentAudio) { - updateTimer() - updateProgressBar() + break + default: + break } - }, 1000) + }, + "player.current.update": (currentAudioManifest) => { + console.log(`Player current audio updated:`, currentAudioManifest) - return () => { - clearInterval(interval) - } - }, [playing]) + this.updateAll() - const events = { - "audioPlayer.seeked": () => { - updateTimer() - updateProgressBar() + this.setState({ + timeText: "00:00", + sliderTime: 0, + }) + + this.calculateDuration() }, - "audioPlayer.playing": () => { - updateDuration() - updateTimer() - updateProgressBar() + "player.duration.update": (duration) => { + console.log(`Player duration updated: ${duration}`) + + this.calculateDuration() }, - "audioPlayer.paused": () => { - setPlaying(false) - }, - "audioPlayer.stopped": () => { - setPlaying(false) + "player.seek.update": (seek) => { + console.log(`Player seek updated: ${seek}`) + + this.calculateTime() + this.updateAll() } } - React.useEffect(() => { - // listen events - for (const [event, callback] of Object.entries(events)) { + tick = () => { + if (this.props.playing) { + this.interval = setInterval(() => { + this.updateAll() + }, 1000) + } else { + clearInterval(this.interval) + } + } + + componentDidMount = () => { + this.calculateDuration() + this.tick() + + for (const [event, callback] of Object.entries(this.events)) { app.eventBus.on(event, callback) } + } - return () => { - // remove events - for (const [event, callback] of Object.entries(events)) { - app.eventBus.off(event, callback) - } + componentWillUnmount = () => { + for (const [event, callback] of Object.entries(this.events)) { + app.eventBus.off(event, callback) } - }, []) + } - return