89 lines
1.4 KiB
Go
89 lines
1.4 KiB
Go
package audio
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/pion/rtp"
|
|
"github.com/pion/webrtc/v3"
|
|
"github.com/pion/webrtc/v3/pkg/media"
|
|
)
|
|
|
|
type Out struct {
|
|
Out []chan *rtp.Packet
|
|
Tracks []*webrtc.TrackLocalStaticSample
|
|
Client []int
|
|
Active []time.Time
|
|
*sync.Mutex
|
|
}
|
|
|
|
func NewOut() *Out {
|
|
out := Out{
|
|
Mutex: new(sync.Mutex),
|
|
}
|
|
|
|
return &out
|
|
}
|
|
|
|
func (o *Out) AddTrack(track *webrtc.TrackLocalStaticSample) {
|
|
o.Lock()
|
|
defer o.Unlock()
|
|
|
|
o.Tracks = append(o.Tracks, track)
|
|
o.Out = append(o.Out, make(chan *rtp.Packet, 10))
|
|
o.Client = append(o.Client, 0)
|
|
o.Active = append(o.Active, time.Time{})
|
|
|
|
go o.handleTrack(len(o.Tracks) - 1)
|
|
}
|
|
|
|
func (o *Out) handleTrack(i int) {
|
|
track := o.Tracks[i]
|
|
var err error
|
|
for p := range o.Out[i] {
|
|
if p == nil {
|
|
return
|
|
}
|
|
|
|
err = track.WriteSample(media.Sample{Data: p.Payload, Duration: Samples})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (o *Out) Write(p *rtp.Packet, source int) {
|
|
o.Lock()
|
|
defer o.Unlock()
|
|
|
|
for i := range o.Out {
|
|
if o.Client[i] == 0 || o.Client[i] == source || time.Since(o.Active[i]) >= 50*time.Millisecond {
|
|
select {
|
|
case o.Out[i] <- p:
|
|
default:
|
|
log.Printf("warning: filled voice out buffer when writing from %d", source)
|
|
continue
|
|
}
|
|
|
|
o.Active[i] = time.Now()
|
|
o.Client[i] = source
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (o *Out) Reset() {
|
|
o.Lock()
|
|
defer o.Unlock()
|
|
|
|
for i := range o.Out {
|
|
o.Out[i] <- nil
|
|
}
|
|
|
|
o.Tracks = nil
|
|
o.Out = nil
|
|
o.Client = nil
|
|
o.Active = nil
|
|
}
|