mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
examples/audio: Implement seeking
This commit is contained in:
parent
0fb5dffbf5
commit
4a4621a126
@ -57,8 +57,40 @@ var (
|
|||||||
audioLoaded bool
|
audioLoaded bool
|
||||||
audioPlayer *audio.Player
|
audioPlayer *audio.Player
|
||||||
total time.Duration
|
total time.Duration
|
||||||
|
mouseButtonState = map[ebiten.MouseButton]int{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func playerBarRect() (x, y, w, h int) {
|
||||||
|
w, h = playerBarImage.Size()
|
||||||
|
x = (screenWidth - w) / 2
|
||||||
|
y = screenHeight - h - 16
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePlayerBar() error {
|
||||||
|
if !audioLoaded {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
|
mouseButtonState[ebiten.MouseButtonLeft] = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
mouseButtonState[ebiten.MouseButtonLeft]++
|
||||||
|
if mouseButtonState[ebiten.MouseButtonLeft] != 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
x, y := ebiten.CursorPosition()
|
||||||
|
bx, by, bw, bh := playerBarRect()
|
||||||
|
if y < by || by+bh <= y {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if x < bx || bx+bw <= x {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
p := time.Duration(x-bx) * total / time.Duration(bw)
|
||||||
|
return audioPlayer.Seek(p)
|
||||||
|
}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
audioContext.Update()
|
audioContext.Update()
|
||||||
if !audioLoaded {
|
if !audioLoaded {
|
||||||
@ -69,11 +101,13 @@ func update(screen *ebiten.Image) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := updatePlayerBar(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
w, h := playerBarImage.Size()
|
x, y, w, h := playerBarRect()
|
||||||
x := float64(screenWidth-w) / 2
|
op.GeoM.Translate(float64(x), float64(y))
|
||||||
y := float64(screenHeight - h - 16)
|
|
||||||
op.GeoM.Translate(x, y)
|
|
||||||
screen.DrawImage(playerBarImage, op)
|
screen.DrawImage(playerBarImage, op)
|
||||||
currentTimeStr := ""
|
currentTimeStr := ""
|
||||||
if audioLoaded && audioPlayer.IsPlaying() {
|
if audioLoaded && audioPlayer.IsPlaying() {
|
||||||
@ -85,12 +119,11 @@ func update(screen *ebiten.Image) error {
|
|||||||
currentTimeStr = fmt.Sprintf("%02d:%02d", m, s)
|
currentTimeStr = fmt.Sprintf("%02d:%02d", m, s)
|
||||||
|
|
||||||
// Bar
|
// Bar
|
||||||
w, _ := playerBarImage.Size()
|
|
||||||
cw, ch := playerCurrentImage.Size()
|
cw, ch := playerCurrentImage.Size()
|
||||||
cx := float64(w)*float64(c)/float64(total) + x - float64(cw)/2
|
cx := int(time.Duration(w)*c/total) + x - cw/2
|
||||||
cy := y - float64(ch-h)/2
|
cy := y - (ch-h)/2
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(cx, cy)
|
op.GeoM.Translate(float64(cx), float64(cy))
|
||||||
screen.DrawImage(playerCurrentImage, op)
|
screen.DrawImage(playerCurrentImage, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@ const (
|
|||||||
channelNum = 2
|
channelNum = 2
|
||||||
bytesPerSample = 2
|
bytesPerSample = 2
|
||||||
bitsPerSample = bytesPerSample * 8
|
bitsPerSample = bytesPerSample * 8
|
||||||
|
|
||||||
|
// TODO: This assumes that channelNum is a power of 2.
|
||||||
|
mask = ^(channelNum*bytesPerSample - 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *mixedPlayersStream) Read(b []byte) (int, error) {
|
func (s *mixedPlayersStream) Read(b []byte) (int, error) {
|
||||||
@ -51,8 +54,6 @@ func (s *mixedPlayersStream) Read(b []byte) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This assumes that channelNum is a power of 2.
|
|
||||||
const mask = ^(channelNum*bytesPerSample - 1)
|
|
||||||
if len(s.context.players) == 0 {
|
if len(s.context.players) == 0 {
|
||||||
l := min(len(b), x-s.writtenBytes)
|
l := min(len(b), x-s.writtenBytes)
|
||||||
l &= mask
|
l &= mask
|
||||||
@ -222,7 +223,8 @@ func (p *Player) Rewind() error {
|
|||||||
|
|
||||||
func (p *Player) Seek(offset time.Duration) error {
|
func (p *Player) Seek(offset time.Duration) error {
|
||||||
p.buf = []byte{}
|
p.buf = []byte{}
|
||||||
o := int64(offset) * int64(p.context.sampleRate) / int64(time.Second)
|
o := int64(offset) * bytesPerSample * channelNum * int64(p.context.sampleRate) / int64(time.Second)
|
||||||
|
o &= mask
|
||||||
pos, err := p.src.Seek(o, 0)
|
pos, err := p.src.Seek(o, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user