diff --git a/index.html b/index.html index e7d67c1..1fa18c3 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,8 @@ playlistButtonBorderColor: '#eee', playlistActiveBorderColor: '#eee', errormsgBackgroundColor: '#ff0022dd', - errormsgTextColor: '#dedede' + errormsgTextColor: '#dedede', + restartOnStreamEndMs: 3000 }); radioPlayer.start(); }); diff --git a/src/index.ts b/src/index.ts index ca92213..84cb719 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,14 +26,15 @@ interface PlayerLocalStorage { } interface Config { - rootElement: HTMLDivElement, + rootElement: HTMLDivElement streams: Array - bgColor: string, - playlistHoverColor: string, - playlistButtonBorderColor: string, + bgColor: string + playlistHoverColor: string + playlistButtonBorderColor: string playlistActiveBorderColor: string - errormsgBackgroundColor: string, + errormsgBackgroundColor: string errormsgTextColor: string + restartOnStreamEndMs: number } const autoplayErrorMsg = @@ -56,6 +57,8 @@ class RadioPlayer { // private playerIcyOptions!: IcecastMetadataPlayerIcyOptions private playerIcyOptions!: IcecastMetadataPlayerIcyOptionsWithCallbacks private marquee!: Marquee + private timeoutStreamEndRestart: ReturnType | undefined + private startedStreamId: number = 1 constructor(config: Config) { this.config = config @@ -66,8 +69,6 @@ class RadioPlayer { } private onClickStreamChoice(streamId: number) { - if (this.playerState.playing && this.playerState.streamId === streamId) - return this.play(streamId) } @@ -82,7 +83,7 @@ class RadioPlayer { this.play(this.playerState.streamId) } - onError(text: string, exc: Error) { + private onError(text: string, exc: Error) { if (exc.name === 'NotAllowedError') { this.playButton.setAttribute('title', autoplayErrorMsg) this.playButton.classList.add('has-error') @@ -92,6 +93,16 @@ class RadioPlayer { } } + private onStreamEnd() { + // console.debug('onStreamEnd', this.playerState) + if ( + this.playerState.playing && this.config.restartOnStreamEndMs && + !this.timeoutStreamEndRestart) + this.timeoutStreamEndRestart = setTimeout( + this.play.bind(this, this.playerState.streamId), + this.config.restartOnStreamEndMs) + } + public start() { // When loading the script tag with "defer", and initializing with onload // DOMContentLoaded might have already been fired at loading @@ -123,11 +134,14 @@ class RadioPlayer { } play(streamId: number) { + if (this.timeoutStreamEndRestart) { + clearTimeout(this.timeoutStreamEndRestart) + this.timeoutStreamEndRestart = undefined + } const url: string = this.config.streams[streamId - 1]?.listenUrl if (!url) return - this.playerState = { playing: true, streamId } - this.storeState() + this.startedStreamId = streamId if (this.icyPlayer) { this.icyPlayer.stop().then((x) => { this.icyPlayer = new IcecastMetadataPlayer(url, this.playerIcyOptions) @@ -197,6 +211,9 @@ class RadioPlayer { this.playButton.innerHTML = '' this.isLoading = false; this.errorWrapper.classList.remove('shown'); + this.playerState = { playing: true, streamId: this.startedStreamId } + this.storeState() + // console.debug('onPlay', this.playerState) }, onRetry: this.markButtonLoading.bind(this), onStop: () => { @@ -205,7 +222,10 @@ class RadioPlayer { const streamTitle = this.config.streams[this.playerState.streamId - 1].streamName this.marquee.changeTo(streamTitle) + this.playerState.playing = false + // console.debug('onStop', this.playerState) }, + onStreamEnd: this.onStreamEnd.bind(this), onError: this.onError.bind(this), } root.classList.remove('hidden') diff --git a/src/sass/player.sass b/src/sass/player.sass index 6df4f2d..72d4dad 100644 --- a/src/sass/player.sass +++ b/src/sass/player.sass @@ -15,6 +15,7 @@ #karolyimusic-webplayer &.hidden display: none + overflow: hidden user-select: none background-color: var(--icyplayer-bgcolor) width: 100% @@ -99,7 +100,6 @@ align-self: center cursor: pointer display: flex - border-radius: .2em border: .15em dotted transparent transition: background-color 200ms linear &.active