beep icon indicating copy to clipboard operation
beep copied to clipboard

Duration of audiostream is 0

Open AnotherCoolDude opened this issue 5 years ago • 1 comments

i try to stream audio from the internet and it is playing nicely, but i can not calculate the duration of the stream (it's actually a podcast). I set up the playback like this:

`

func playRemoteFile() {
resp, err := http.Get("https://traffic.libsyn.com/wakingup/Making_Sense_156_Nicholas_Christakis.mp3")


if err != nil {
	log.Fatal(err)
}

streamer, format, err := mp3.Decode(resp.Body)
if err != nil {
	log.Fatal(err)
}
defer streamer.Close()

speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

ctrlStreamer := &beep.Ctrl{Streamer: streamer, Paused: false}

done := make(chan bool)
speaker.Play(beep.Seq(ctrlStreamer, beep.Callback(func() {
	done <- true
})))

for {
	select {
	case <-done:
		return
	case <-time.After(time.Second):
		speaker.Lock()
		fmt.Printf("time elapsed: %d of %d\n", format.SampleRate.D(streamer.Position()), format.SampleRate.D(streamer.Len()))
		speaker.Unlock()
	}
}

}

`

streamer.Len() returns 0. the response contains only the content length. Is it possible to somehow calculate the duration?

AnotherCoolDude avatar May 15 '19 22:05 AnotherCoolDude

From what I've deduced from here (the package that Beep uses to decode MP3), the io.Reader that you're reading from needs to be an io.Seeker if you want the length info to be correct. This is because to calculate the length, it quickly skips through the whole stream, accumulates length and then seeks back to the front.

In other words, the file needs to be fully scanned before the length can be known and I guess dynamically streaming it from the server doesn't make that happen.

I'm not sure if this is the only way to get the length of an MP3 file, but that's how it's doing it. It's quite possible it can't be done any other way.

So, you might try another format if there's any available.

Anyway, good podcast choice :)

faiface avatar May 15 '19 23:05 faiface