2021-09-27 11:50:49 +13:00
|
|
|
package webrtc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"demodesk/neko/internal/types"
|
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/pion/webrtc/v3"
|
|
|
|
"github.com/pion/webrtc/v3/pkg/media"
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
)
|
|
|
|
|
2021-12-02 08:30:18 +13:00
|
|
|
func (manager *WebRTCManagerCtx) newPeerStreamTrack(stream types.StreamSinkManager, logger zerolog.Logger) (*PeerStreamTrack, error) {
|
2021-09-27 11:50:49 +13:00
|
|
|
codec := stream.Codec()
|
|
|
|
|
|
|
|
id := codec.Type.String()
|
|
|
|
track, err := webrtc.NewTrackLocalStaticSample(codec.Capability, id, "stream")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
logger = logger.With().Str("id", id).Logger()
|
|
|
|
|
2021-10-01 11:02:54 +13:00
|
|
|
peer := &PeerStreamTrack{
|
2021-09-27 11:50:49 +13:00
|
|
|
logger: logger,
|
|
|
|
track: track,
|
|
|
|
listener: func(sample types.Sample) {
|
|
|
|
err := track.WriteSample(media.Sample(sample))
|
|
|
|
if err != nil && errors.Is(err, io.ErrClosedPipe) {
|
|
|
|
logger.Warn().Err(err).Msg("pipeline failed to write")
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-10-02 00:46:10 +13:00
|
|
|
err = peer.SetStream(stream)
|
|
|
|
return peer, err
|
2021-09-27 11:50:49 +13:00
|
|
|
}
|
|
|
|
|
2021-10-01 11:02:54 +13:00
|
|
|
type PeerStreamTrack struct {
|
2021-09-27 11:50:49 +13:00
|
|
|
logger zerolog.Logger
|
|
|
|
track *webrtc.TrackLocalStaticSample
|
|
|
|
listener func(sample types.Sample)
|
|
|
|
|
2021-12-02 08:30:18 +13:00
|
|
|
stream types.StreamSinkManager
|
2021-10-01 11:02:54 +13:00
|
|
|
streamMu sync.Mutex
|
2021-09-27 11:50:49 +13:00
|
|
|
}
|
|
|
|
|
2021-12-02 08:30:18 +13:00
|
|
|
func (peer *PeerStreamTrack) SetStream(stream types.StreamSinkManager) error {
|
2021-09-27 11:50:49 +13:00
|
|
|
peer.streamMu.Lock()
|
|
|
|
defer peer.streamMu.Unlock()
|
|
|
|
|
2021-10-02 00:46:10 +13:00
|
|
|
var err error
|
2021-09-27 11:50:49 +13:00
|
|
|
if peer.stream != nil {
|
2021-10-02 00:46:10 +13:00
|
|
|
err = peer.stream.MoveListenerTo(&peer.listener, stream)
|
|
|
|
} else {
|
2021-10-03 00:51:22 +13:00
|
|
|
err = stream.AddListener(&peer.listener)
|
2021-09-27 11:50:49 +13:00
|
|
|
}
|
|
|
|
|
2021-10-03 00:51:22 +13:00
|
|
|
if err == nil {
|
2021-10-02 00:46:10 +13:00
|
|
|
peer.stream = stream
|
2021-09-29 12:03:39 +13:00
|
|
|
}
|
2021-09-27 11:50:49 +13:00
|
|
|
|
2021-10-02 00:46:10 +13:00
|
|
|
return err
|
2021-09-27 11:50:49 +13:00
|
|
|
}
|
|
|
|
|
2021-10-01 11:02:54 +13:00
|
|
|
func (peer *PeerStreamTrack) RemoveStream() {
|
2021-09-27 11:50:49 +13:00
|
|
|
peer.streamMu.Lock()
|
|
|
|
defer peer.streamMu.Unlock()
|
|
|
|
|
|
|
|
if peer.stream != nil {
|
2021-10-08 08:41:19 +13:00
|
|
|
_ = peer.stream.RemoveListener(&peer.listener)
|
2021-10-02 00:46:10 +13:00
|
|
|
peer.stream = nil
|
2021-09-27 11:50:49 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-01 11:02:54 +13:00
|
|
|
func (peer *PeerStreamTrack) AddToConnection(connection *webrtc.PeerConnection) error {
|
2021-09-27 11:50:49 +13:00
|
|
|
sender, err := connection.AddTrack(peer.track)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
rtcpBuf := make([]byte, 1500)
|
|
|
|
for {
|
|
|
|
if _, _, err := sender.Read(rtcpBuf); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|