diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a5c36a6..fda5712 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,7 +21,7 @@ ], "postStartCommand": "sudo setfacl -m u:vscode:rw /dev/snd/*", // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], + "forwardPorts": [5901, 6080], // Use 'postCreateCommand' to run commands after the container is created. "onCreateCommand": { "log": "echo 'Starting post-create script...'", @@ -29,4 +29,4 @@ "config": "bash -c 'mkdir -p ~/.config/supersonic && (cp .devcontainer/custom-config.toml ~/.config/supersonic/config.toml 2> /dev/null || cp .devcontainer/default-config.toml ~/.config/supersonic/config.toml)'", "keyring": "bash -c '.devcontainer/init-keychain.sh'", }, -} \ No newline at end of file +} diff --git a/backend/app.go b/backend/app.go index e23b170..4d66c90 100644 --- a/backend/app.go +++ b/backend/app.go @@ -384,6 +384,7 @@ func (a *App) setupMPV() error { PreampGain: a.Config.ReplayGain.PreampGainDB, }) a.LocalPlayer.SetAudioExclusive(a.Config.LocalPlayback.AudioExclusive) + a.LocalPlayer.SetPauseFade(a.Config.LocalPlayback.PauseFade) eq := &mpv.ISO15BandEqualizer{ EQPreamp: a.Config.LocalPlayback.EqualizerPreamp, diff --git a/backend/config.go b/backend/config.go index cadad20..139c497 100644 --- a/backend/config.go +++ b/backend/config.go @@ -136,6 +136,7 @@ type LocalPlaybackConfig struct { EqualizerEnabled bool EqualizerPreamp float64 GraphicEqualizerBands []float64 + PauseFade bool } type ScrobbleConfig struct { @@ -270,6 +271,7 @@ func DefaultConfig(appVersionTag string) *Config { EqualizerEnabled: false, EqualizerPreamp: 0, GraphicEqualizerBands: make([]float64, 15), + PauseFade: true, }, Scrobbling: ScrobbleConfig{ Enabled: true, diff --git a/backend/player/mpv/player.go b/backend/player/mpv/player.go index 6ca65bc..a6a9cf6 100644 --- a/backend/player/mpv/player.go +++ b/backend/player/mpv/player.go @@ -69,6 +69,7 @@ type Player struct { clientName string equalizer Equalizer peaksEnabled bool + pauseFade bool fileLoadedLock sync.Mutex fileLoadedSig *sync.Cond @@ -283,6 +284,10 @@ func (p *Player) SetAudioExclusive(tf bool) { } } +func (p *Player) SetPauseFade(pauseFade bool) { + p.pauseFade = pauseFade +} + // Gets the current volume of the player. func (p *Player) GetVolume() int { return p.vol @@ -308,27 +313,37 @@ func (p *Player) Pause() error { if p.status.State != player.Playing { return nil } - p.prePausedState = p.status.State - p.setState(player.Paused) - v := p.vol - ctx, cancel := context.WithCancel(context.Background()) - p.fadePauseCancel = cancel - go func() { - t := time.NewTicker(2 * time.Millisecond) - for c := 0; c < 100; c++ { - select { - case <-ctx.Done(): - return - case <-t.C: - p.mpv.SetProperty("volume", mpv.FORMAT_INT64, int64(v*(100-c)/100)) + if p.pauseFade { + p.prePausedState = p.status.State + p.setState(player.Paused) + + v := p.vol + ctx, cancel := context.WithCancel(context.Background()) + p.fadePauseCancel = cancel + go func() { + t := time.NewTicker(2 * time.Millisecond) + for c := 0; c < 100; c++ { + select { + case <-ctx.Done(): + return + case <-t.C: + p.mpv.SetProperty("volume", mpv.FORMAT_INT64, int64(v*(100-c)/100)) + } } + t.Stop() + p.SetVolume(p.vol) + p.setPaused(true) + }() + return nil + } else { + err := p.setPaused(true) + if err == nil { + p.prePausedState = p.status.State + p.setState(player.Paused) } - t.Stop() - p.SetVolume(p.vol) - p.setPaused(true) - }() - return nil + return err + } } // Continue playback and update the player state diff --git a/res/translations/en.json b/res/translations/en.json index 0f84174..da1d315 100644 --- a/res/translations/en.json +++ b/res/translations/en.json @@ -94,6 +94,7 @@ "Error": "Error", "Error creating playlist": "Error creating playlist", "Exclusive mode": "Exclusive mode", + "Fade out on pause": "Fade out on pause", "Favorites": "Favorites", "Field Recording": "Field Recording", "File path": "File path", @@ -331,4 +332,4 @@ "one": "{{.albumsCount}} album", "other": "{{.albumsCount}} albums" } -} \ No newline at end of file +} diff --git a/ui/controller/controller.go b/ui/controller/controller.go index 65d3729..9c9421a 100644 --- a/ui/controller/controller.go +++ b/ui/controller/controller.go @@ -334,6 +334,9 @@ func (c *Controller) ShowSettingsDialog(themeUpdateCallbk func(), themeFiles map dlg.OnAudioExclusiveSettingChanged = func() { c.App.LocalPlayer.SetAudioExclusive(c.App.Config.LocalPlayback.AudioExclusive) } + dlg.OnPauseFadeSettingsChanged = func() { + c.App.LocalPlayer.SetPauseFade(c.App.Config.LocalPlayback.PauseFade) + } dlg.OnAudioDeviceSettingChanged = func() { c.App.LocalPlayer.SetAudioDevice(c.App.Config.LocalPlayback.AudioDeviceName) } diff --git a/ui/dialogs/settingsdialog.go b/ui/dialogs/settingsdialog.go index 854fd20..9173289 100644 --- a/ui/dialogs/settingsdialog.go +++ b/ui/dialogs/settingsdialog.go @@ -33,6 +33,7 @@ type SettingsDialog struct { OnReplayGainSettingsChanged func() OnAudioExclusiveSettingChanged func() + OnPauseFadeSettingsChanged func() OnAudioDeviceSettingChanged func() OnThemeSettingChanged func() OnDismiss func() @@ -407,9 +408,18 @@ func (s *SettingsDialog) createPlaybackTab(isLocalPlayer, isReplayGainPlayer boo }) audioExclusive.Checked = s.config.LocalPlayback.AudioExclusive + pauseFade := widget.NewCheck(lang.L("Fade out on pause"), func(checked bool) { + s.config.LocalPlayback.PauseFade = checked + if s.OnPauseFadeSettingsChanged != nil { + s.OnPauseFadeSettingsChanged() + } + }) + pauseFade.Checked = s.config.LocalPlayback.PauseFade + if !isLocalPlayer { deviceSelect.Disable() audioExclusive.Disable() + pauseFade.Disable() } if !isReplayGainPlayer { replayGainSelect.Disable() @@ -424,6 +434,7 @@ func (s *SettingsDialog) createPlaybackTab(isLocalPlayer, isReplayGainPlayer boo widget.NewLabel(lang.L("Audio device")), container.NewBorder(nil, nil, nil, util.NewHSpace(70), deviceSelect), layout.NewSpacer(), audioExclusive, )), + pauseFade, s.newSectionSeparator(), disableTranscode, container.NewHBox(transcode, transcodeCodec, transcodeBitRate),