audio player basics complete

This commit is contained in:
2025-04-09 14:03:33 -04:00
parent 660acb384f
commit 42d5eb94ff
+28 -2
View File
@@ -3,6 +3,7 @@ package player
import ( import (
"context" "context"
"fmt" "fmt"
"math"
"os" "os"
"time" "time"
@@ -19,6 +20,7 @@ type Player struct {
currentFile *os.File currentFile *os.File
format beep.Format format beep.Format
baseStreamer beep.Streamer baseStreamer beep.Streamer
seeker beep.StreamSeeker
resampled beep.Streamer resampled beep.Streamer
control *beep.Ctrl control *beep.Ctrl
volume *effects.Volume volume *effects.Volume
@@ -54,14 +56,14 @@ func (p *Player) Init(ctx context.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to initialize speaker %w", err) return fmt.Errorf("failed to initialize speaker %w", err)
} }
p.updateStreamers(p.baseStreamer, p.format.SampleRate)
return nil return nil
} }
func (p *Player) updateStreamers(newBaseStreamer beep.Streamer, sr beep.SampleRate) error { func (p *Player) updateStreamers(newBaseStreamer beep.StreamSeeker, sr beep.SampleRate) error {
// set base streamer // set base streamer
p.baseStreamer = newBaseStreamer p.baseStreamer = newBaseStreamer
p.seeker = newBaseStreamer
// resample file stream to match speaker // resample file stream to match speaker
// TODO: variable resample quality // TODO: variable resample quality
@@ -103,6 +105,8 @@ func (p *Player) LoadFile(filePath string) error {
return fmt.Errorf("failed to decode mp3 %w", err) return fmt.Errorf("failed to decode mp3 %w", err)
} }
p.currentFile = f
p.updateStreamers(streamer, format.SampleRate) p.updateStreamers(streamer, format.SampleRate)
return nil return nil
@@ -145,12 +149,14 @@ Positive Volume value means increasing volume
Negative Volume value means decreasing volume Negative Volume value means decreasing volume
*/ */
func (p *Player) SetVolume(desiredVolume UserVolume) error { func (p *Player) SetVolume(desiredVolume UserVolume) error {
speaker.Lock()
// clamp value between 1 and 100 // clamp value between 1 and 100
volume := clampVolume(desiredVolume) volume := clampVolume(desiredVolume)
// Apply the volume settings // Apply the volume settings
p.volume.Volume = float64(volume.ToPlayerVolume()) p.volume.Volume = float64(volume.ToPlayerVolume())
p.volume.Silent = volume == MinUserVol p.volume.Silent = volume == MinUserVol
speaker.Unlock()
return nil return nil
} }
@@ -166,3 +172,23 @@ func (p *Player) MuteToggle() error {
p.volume.Silent = !p.volume.Silent p.volume.Silent = !p.volume.Silent
return nil return nil
} }
// return the current position as an int between 0 and 100 to work with progress bar easily.
func (p *Player) CurrentPosition() (float64, error) {
pos := 100.0 * float64(p.seeker.Position()) / float64(p.seeker.Len())
return pos, nil
}
// TODO: double check best type for percentage parameter
// percentage comes from the progress bar as a value between 0 and 100
func (p *Player) Seek(percentage int) error {
//take percentage value (0-100), make 0-1, multiply by total number of samples in stream
samples := int(math.Round((float64(percentage) / 100.0) * float64(p.seeker.Len())))
p.seeker.Seek(samples)
return nil
}
func (p *Player) TrackLengthInSeconds() (int, error) {
len := p.seeker.Len() / int(p.format.SampleRate)
return len, nil
}