Skip to content

Commit eb63eb9

Browse files
committed
Unexport Frame, update readme and example
1 parent 3184097 commit eb63eb9

File tree

4 files changed

+24
-20
lines changed

4 files changed

+24
-20
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# audiostream
2+
[![GoDoc](https://godoc.org/github.com/davidae/audiostream?status.svg)](https://godoc.org/github.com/davidae/audiostream)
3+
24
audiostream is a simple streaming API for audio files. It can easily be used
3-
together with a HTTP server to stream audio.
5+
together with a HTTP server to stream audio to a HTTP client.
46

57
This is package is used in an ongoing effort together with another private project.
68

@@ -10,8 +12,8 @@ This is package is used in an ongoing effort together with another private proje
1012
* It will broadcast the files to any listeners in frames of bytes and the listeners can be read as a stream via channels.
1113

1214
## What does the API _not_ do?
13-
* It does not implement the SHOUTcast_ or _Icecast_ protocol.
14-
* It cannot decode or convert audio files. A decoder package can solve this and _ffmpeg_ can deal with converting sample rates if needed.
15+
* It does not implement the _SHOUTcast_ or _Icecast_ protocol.
16+
* It cannot decode, convert or manipulate audio files. Its up to the implementor to deal with this. A [decoder package](https://github.com/hajimehoshi/go-mp3) can solve this and _ffmpeg_ can deal with converting sample rates if needed.
1517

1618
# Example
1719
See how to use the audiostream together with an HTTP server in [examples/main.go](https://github.com/davidae/audiostream/blob/master/example/main.go)
@@ -28,8 +30,7 @@ import (
2830
)
2931

3032
func main() {
31-
lazyFileRead := audiostream.WithFramzeSize(2)
32-
stream := audiostream.NewStream(lazyFileRead)
33+
stream := audiostream.NewStream(audiostream.WithFramzeSize(2))
3334

3435
stream.AppendAudio(&audiostream.Audio{
3536
Data: strings.NewReader("thisIsForSureNotAProperAudioFileThough"),
@@ -59,4 +60,4 @@ func main() {
5960
* https://stackoverflow.com/questions/35102278/python-3-get-song-name-from-internet-radio-stream
6061
* https://github.com/krotik/dudeldu
6162
* https://gist.github.com/jucrouzet/3e59877c0b4352966e6220034f2b84ac
62-
* https://stackoverflow.com/a/57634692
63+
* https://stackoverflow.com/a/57634692

example/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func main() {
2323
Artist: "Fizz",
2424
Title: "Buzz",
2525
Filename: "your-mp3-file.mp3",
26-
SampleRate: 44100,
26+
SampleRate: 44100, // a naive assumption, use a decoder to know for sure.
2727
})
2828

2929
http.HandleFunc("/audio", func(w http.ResponseWriter, r *http.Request) {
@@ -46,7 +46,7 @@ func main() {
4646
for !endLoop {
4747
select {
4848
case <-time.After(time.Second * 2):
49-
// client timed out
49+
// timeout
5050
endLoop = true
5151
case out := <-listener.Stream():
5252
binary.Write(w, binary.BigEndian, out)
@@ -66,4 +66,5 @@ func main() {
6666
http.ListenAndServe(":8080", nil)
6767
}
6868

69+
// To easily listen in,
6970
// mplayer http://localhost:8080/audio -v

listener.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import (
44
"github.com/gofrs/uuid"
55
)
66

7+
// Listener is a client used to listen to the stream of audio
78
type Listener struct {
89
uuid string
9-
frame chan Frame
10+
frame chan frame
1011
stream chan []byte
1112
startedToStream bool
1213
metadataInterval int64
@@ -36,7 +37,7 @@ func NewListener(opts ...ListenerOption) (*Listener, error) {
3637
l := &Listener{
3738
uuid: uuid.String(),
3839
stream: make(chan []byte),
39-
frame: make(chan Frame),
40+
frame: make(chan frame),
4041
}
4142

4243
for _, o := range opts {

stream.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
)
1111

1212
const (
13-
defaultListenerTimeout = time.Millisecond * 500
1413
defaultFrameSize = 3000
1514
defaultMetadataInterval = 65536
1615

@@ -29,7 +28,8 @@ var (
2928
// StreamOption is a func used to configure the streamer upon initialization
3029
type StreamOption func(s *Stream)
3130

32-
// WithFramzeSize sets the frame size, which if the size of bytes used when reading a block of audio
31+
// WithFramzeSize sets the frame size, which if the size of bytes used when reading a block of audio.
32+
// The default frame size is 3000
3333
func WithFramzeSize(size int) StreamOption {
3434
return func(s *Stream) { s.frameSize = size }
3535
}
@@ -45,8 +45,9 @@ func DefaultSleepForFunc() SleepFor {
4545
}
4646

4747
// WithLazyFileRead is an option that will halt the stream from reading an audio file overzealously and
48-
// passing it on to the listeners. This can be useful if we want to keep the in-memory low and
49-
// avoid often empty queueus
48+
// passing it on to the listeners. This can be useful if we want to keep the in-memory low,
49+
// provide a "now playing" functionality without using the `ICY protocol` (be in sync with what the client is reading),
50+
// avoid overflowing the buffer reading the stream (f.ex. an HTTP client) and avoid often empty queues
5051
func WithLazyFileRead(fn SleepFor) StreamOption {
5152
return func(s *Stream) {
5253
s.lazyFileReading = true
@@ -65,15 +66,15 @@ type Audio struct {
6566
// Read will read the audio data
6667
func (a *Audio) Read(b []byte) (int, error) { return a.Data.Read(b) }
6768

68-
// Frame is a simple abstraction of what a stream will send to its listeners
69-
type Frame struct {
69+
// frame is a simple abstraction of what a stream will send to its listeners
70+
type frame struct {
7071
data []byte
7172
title, artist string
7273
}
7374

7475
// ShoutcastMetadata will build a frame to send metadata to a client that can
7576
// decode/parse ShoutCast metadata as a part of the audio stream from a listener
76-
func (f Frame) ShoutcastMetadata() []byte {
77+
func (f frame) ShoutcastMetadata() []byte {
7778
meta := fmt.Sprintf("StreamTitle='%v - %v';", f.artist, f.title)
7879

7980
// is it above max size?
@@ -188,8 +189,8 @@ func (s *Stream) Start() error {
188189
}
189190

190191
// read a frame from audio
191-
frame := make([]byte, s.frameSize)
192-
bytes, err := s.reading.Read(frame)
192+
dataFrame := make([]byte, s.frameSize)
193+
bytes, err := s.reading.Read(dataFrame)
193194
if err != nil {
194195
// we are done reading this audio file
195196
if err == io.EOF {
@@ -210,7 +211,7 @@ func (s *Stream) Start() error {
210211
wg.Add(len(s.listeners))
211212
for _, l := range s.listeners {
212213
go func(l *Listener) {
213-
l.frame <- Frame{data: frame, artist: s.reading.Artist, title: s.reading.Title}
214+
l.frame <- frame{data: dataFrame, artist: s.reading.Artist, title: s.reading.Title}
214215
wg.Done()
215216
}(l)
216217
}

0 commit comments

Comments
 (0)