mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 13:17:46 +00:00
feat(utils/player): 播放、暂停时淡入淡出 (#1433)
Co-Authored-By: pan93412 <pan93412@gmail.com> Co-authored-by: pan93412 <pan93412@gmail.com>
This commit is contained in:
parent
7ac084f73d
commit
3b9d728410
1 changed files with 46 additions and 8 deletions
|
|
@ -4,6 +4,7 @@ import {
|
||||||
fetchTracksWithReactQuery,
|
fetchTracksWithReactQuery,
|
||||||
} from '@/hooks/useTracks'
|
} from '@/hooks/useTracks'
|
||||||
import { cacheAudio } from '@/api/yesplaymusic'
|
import { cacheAudio } from '@/api/yesplaymusic'
|
||||||
|
import { clamp } from 'lodash-es'
|
||||||
|
|
||||||
type TrackID = number
|
type TrackID = number
|
||||||
enum TrackListSourceType {
|
enum TrackListSourceType {
|
||||||
|
|
@ -31,12 +32,15 @@ export enum RepeatMode {
|
||||||
ONE = 'one',
|
ONE = 'one',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PLAY_PAUSE_FADE_DURATION = 200
|
||||||
|
|
||||||
let _howler = new Howl({ src: [''], format: ['mp3', 'flac'] })
|
let _howler = new Howl({ src: [''], format: ['mp3', 'flac'] })
|
||||||
export class Player {
|
export class Player {
|
||||||
private _track: Track | null = null
|
private _track: Track | null = null
|
||||||
private _trackIndex: number = 0
|
private _trackIndex: number = 0
|
||||||
private _progress: number = 0
|
private _progress: number = 0
|
||||||
private _progressInterval: ReturnType<typeof setInterval> | undefined
|
private _progressInterval: ReturnType<typeof setInterval> | undefined
|
||||||
|
private _volume: number = 1 // 0 to 1
|
||||||
|
|
||||||
state: State = State.INITIALIZING
|
state: State = State.INITIALIZING
|
||||||
mode: Mode = Mode.PLAYLIST
|
mode: Mode = Mode.PLAYLIST
|
||||||
|
|
@ -107,6 +111,17 @@ export class Player {
|
||||||
_howler.seek(value)
|
_howler.seek(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get/Set current volume
|
||||||
|
*/
|
||||||
|
get volume(): number {
|
||||||
|
return this._volume
|
||||||
|
}
|
||||||
|
set volume(value) {
|
||||||
|
this._volume = clamp(value, 0, 1)
|
||||||
|
Howler.volume(this._volume)
|
||||||
|
}
|
||||||
|
|
||||||
private _setupProgressInterval() {
|
private _setupProgressInterval() {
|
||||||
this._progressInterval = setInterval(() => {
|
this._progressInterval = setInterval(() => {
|
||||||
if (this.state === State.PLAYING) this._progress = _howler.seek()
|
if (this.state === State.PLAYING) this._progress = _howler.seek()
|
||||||
|
|
@ -144,7 +159,6 @@ export class Player {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play audio via howler
|
* Play audio via howler
|
||||||
* @param {string} audio audio source url
|
|
||||||
*/
|
*/
|
||||||
private async _playAudio() {
|
private async _playAudio() {
|
||||||
const audio = await this._fetchAudioSource(this.trackID)
|
const audio = await this._fetchAudioSource(this.trackID)
|
||||||
|
|
@ -190,26 +204,50 @@ export class Player {
|
||||||
* Play current track
|
* Play current track
|
||||||
* @param {boolean} fade fade in
|
* @param {boolean} fade fade in
|
||||||
*/
|
*/
|
||||||
play() {
|
play(fade: boolean = false) {
|
||||||
if (_howler.playing()) return
|
if (_howler.playing()) return
|
||||||
|
|
||||||
|
const setPlayState = () => {
|
||||||
|
this.state = State.PLAYING
|
||||||
|
}
|
||||||
|
|
||||||
_howler.play()
|
_howler.play()
|
||||||
this.state = State.PLAYING
|
if (fade) {
|
||||||
|
_howler.once('play', () => {
|
||||||
|
_howler.fade(0, this._volume, PLAY_PAUSE_FADE_DURATION)
|
||||||
|
setPlayState()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setPlayState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause current track
|
* Pause current track
|
||||||
* @param {boolean} fade fade out
|
* @param {boolean} fade fade out
|
||||||
*/
|
*/
|
||||||
pause() {
|
pause(fade: boolean = false) {
|
||||||
_howler.pause()
|
const setPauseState = () => {
|
||||||
this.state = State.PAUSED
|
_howler.pause()
|
||||||
|
this.state = State.PAUSED
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fade) {
|
||||||
|
_howler.fade(this._volume, 0, PLAY_PAUSE_FADE_DURATION)
|
||||||
|
_howler.once('fade', () => {
|
||||||
|
setPauseState()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setPauseState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play or pause current track
|
* Play or pause current track
|
||||||
|
* @param {boolean} fade fade in-out
|
||||||
*/
|
*/
|
||||||
playOrPause() {
|
playOrPause(fade: boolean = true) {
|
||||||
this.state === State.PLAYING ? this.pause() : this.play()
|
this.state === State.PLAYING ? this.pause(fade) : this.play(fade)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue