mirror of
https://github.com/pion/mediadevices.git
synced 2025-09-26 20:41:46 +08:00
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package audio
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/pion/mediadevices/pkg/io"
|
|
"github.com/pion/mediadevices/pkg/wave"
|
|
)
|
|
|
|
var errEmptySource = errors.New("Source can't be nil")
|
|
|
|
// Broadcaster is a specialized video broadcaster.
|
|
type Broadcaster struct {
|
|
ioBroadcaster *io.Broadcaster
|
|
}
|
|
|
|
type BroadcasterConfig struct {
|
|
Core *io.BroadcasterConfig
|
|
}
|
|
|
|
// NewBroadcaster creates a new broadcaster. Source is expected to drop chunks
|
|
// when any of the readers is slower than the source.
|
|
func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
|
|
var coreConfig *io.BroadcasterConfig
|
|
|
|
if config != nil {
|
|
coreConfig = config.Core
|
|
}
|
|
|
|
broadcaster := io.NewBroadcaster(io.ReaderFunc(func() (interface{}, func(), error) {
|
|
return source.Read()
|
|
}), coreConfig)
|
|
|
|
return &Broadcaster{broadcaster}
|
|
}
|
|
|
|
// NewReader creates a new reader. Each reader will retrieve the same data from the source.
|
|
// copyFn is used to copy the data from the source to individual readers. Broadcaster uses a small ring
|
|
// buffer, this means that slow readers might miss some data if they're really late and the data is no longer
|
|
// in the ring buffer.
|
|
func (broadcaster *Broadcaster) NewReader(copyChunk bool) Reader {
|
|
copyFn := func(src interface{}) interface{} { return src }
|
|
|
|
if copyChunk {
|
|
buffer := wave.NewBuffer()
|
|
copyFn = func(src interface{}) interface{} {
|
|
realSrc, _ := src.(wave.Audio)
|
|
buffer.StoreCopy(realSrc)
|
|
return buffer.Load()
|
|
}
|
|
}
|
|
|
|
reader := broadcaster.ioBroadcaster.NewReader(copyFn)
|
|
return ReaderFunc(func() (wave.Audio, func(), error) {
|
|
data, _, err := reader.Read()
|
|
chunk, _ := data.(wave.Audio)
|
|
return chunk, func() {}, err
|
|
})
|
|
}
|
|
|
|
// ReplaceSource replaces the underlying source. This operation is thread safe.
|
|
func (broadcaster *Broadcaster) ReplaceSource(source Reader) error {
|
|
return broadcaster.ioBroadcaster.ReplaceSource(io.ReaderFunc(func() (interface{}, func(), error) {
|
|
return source.Read()
|
|
}))
|
|
}
|
|
|
|
// Source retrieves the underlying source. This operation is thread safe.
|
|
func (broadcaster *Broadcaster) Source() Reader {
|
|
source := broadcaster.ioBroadcaster.Source()
|
|
return ReaderFunc(func() (wave.Audio, func(), error) {
|
|
data, _, err := source.Read()
|
|
img, _ := data.(wave.Audio)
|
|
return img, func() {}, err
|
|
})
|
|
}
|