replace video track on demand.

This commit is contained in:
Miroslav Šedivý 2021-02-05 20:35:30 +01:00
parent c81bca9b2f
commit 6756114e30
6 changed files with 42 additions and 23 deletions

View File

@ -11,6 +11,7 @@ const (
SIGNAL_ANSWER = "signal/answer"
SIGNAL_PROVIDE = "signal/provide"
SIGNAL_CANDIDATE = "signal/candidate"
SIGNAL_VIDEO = "signal/video"
)
const (

View File

@ -57,6 +57,11 @@ type SignalAnswer struct {
SDP string `json:"sdp"`
}
type SignalVideo struct {
Event string `json:"event,omitempty"`
VideoID string `json:"video_id"`
}
/////////////////////////////
// Member
/////////////////////////////

View File

@ -57,6 +57,8 @@ func (manager *WebRTCManagerCtx) Start() {
videoIDs := manager.capture.VideoIDs()
manager.videoTracks = map[string]*webrtc.TrackLocalStaticSample{}
for _, videoID := range videoIDs {
videoID := videoID
video, ok := manager.capture.Video(videoID)
if !ok {
manager.logger.Warn().Str("videoID", videoID).Msg("video stream not found, skipping")
@ -65,12 +67,12 @@ func (manager *WebRTCManagerCtx) Start() {
track, err := webrtc.NewTrackLocalStaticSample(video.Codec().Capability, "video", "stream")
if err != nil {
manager.logger.Panic().Err(err).Msgf("unable to create video (%s) track", videoID)
manager.logger.Panic().Err(err).Str("videoID", videoID).Msg("unable to create video track")
}
video.OnSample(func(sample types.Sample) {
if err := track.WriteSample(media.Sample(sample)); err != nil && err != io.ErrClosedPipe {
manager.logger.Warn().Err(err).Msgf("video (%s) pipeline failed to write", videoID)
manager.logger.Warn().Err(err).Str("videoID", videoID).Msg("vide pipeline failed to write")
}
})
@ -141,16 +143,12 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session) (*webrtc.Sess
})
}
_, err = connection.AddTransceiverFromTrack(manager.audioTrack, webrtc.RtpTransceiverInit{
Direction: webrtc.RTPTransceiverDirectionSendonly,
})
_, err = connection.AddTrack(manager.audioTrack)
if err != nil {
return nil, err
}
videoTransceiver, err := connection.AddTransceiverFromTrack(manager.videoTracks[manager.defaultVideoID], webrtc.RtpTransceiverInit{
Direction: webrtc.RTPTransceiverDirectionSendonly,
})
videoSender, err := connection.AddTrack(manager.videoTracks[manager.defaultVideoID])
if err != nil {
return nil, err
}
@ -206,13 +204,13 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session) (*webrtc.Sess
})
session.SetWebRTCPeer(&WebRTCPeerCtx{
api: api,
engine: engine,
settings: settings,
connection: connection,
configuration: configuration,
videoTracks: manager.videoTracks,
videoTransceiver: videoTransceiver,
api: api,
engine: engine,
settings: settings,
connection: connection,
configuration: configuration,
videoTracks: manager.videoTracks,
videoSender: videoSender,
})
return connection.LocalDescription(), nil

View File

@ -7,13 +7,13 @@ import (
)
type WebRTCPeerCtx struct {
api *webrtc.API
engine *webrtc.MediaEngine
settings *webrtc.SettingEngine
connection *webrtc.PeerConnection
configuration *webrtc.Configuration
videoTracks map[string]*webrtc.TrackLocalStaticSample
videoTransceiver *webrtc.RTPTransceiver
api *webrtc.API
engine *webrtc.MediaEngine
settings *webrtc.SettingEngine
connection *webrtc.PeerConnection
configuration *webrtc.Configuration
videoTracks map[string]*webrtc.TrackLocalStaticSample
videoSender *webrtc.RTPSender
}
func (webrtc_peer *WebRTCPeerCtx) SignalAnswer(sdp string) error {
@ -33,7 +33,7 @@ func (webrtc_peer *WebRTCPeerCtx) SetVideoID(videoID string) error {
return fmt.Errorf("videoID not found in available tracks")
}
return webrtc_peer.videoTransceiver.Sender().ReplaceTrack(track)
return webrtc_peer.videoSender.ReplaceTrack(track)
}
func (webrtc_peer *WebRTCPeerCtx) Destroy() error {

View File

@ -59,6 +59,11 @@ func (h *MessageHandlerCtx) Message(session types.Session, raw []byte) bool {
err = utils.Unmarshal(payload, raw, func() error {
return h.signalCandidate(session, payload)
})
case event.SIGNAL_VIDEO:
payload := &message.SignalVideo{}
err = utils.Unmarshal(payload, raw, func() error {
return h.signalVideo(session, payload)
})
// Control Events
case event.CONTROL_RELEASE:

View File

@ -44,3 +44,13 @@ func (h *MessageHandlerCtx) signalCandidate(session types.Session, payload *mess
return peer.SignalCandidate(*payload.ICECandidateInit)
}
func (h *MessageHandlerCtx) signalVideo(session types.Session, payload *message.SignalVideo) error {
peer := session.GetWebRTCPeer()
if peer == nil {
h.logger.Debug().Msg("webRTC peer does not exist")
return nil
}
return peer.SetVideoID(payload.VideoID)
}