This commit is contained in:
Lukas Herman
2020-08-19 18:48:22 -07:00
parent 7a4ca55b41
commit c4e7159480
3 changed files with 134 additions and 38 deletions

101
rtp.go Normal file
View File

@@ -0,0 +1,101 @@
package mediadevices
import (
"fmt"
"github.com/pion/mediadevices/pkg/codec"
"github.com/pion/mediadevices/pkg/prop"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/webrtc/v2"
)
type RTPTracker struct {
videoEncoders []codec.VideoEncoderBuilder
audioEncoders []codec.AudioEncoderBuilder
}
type RTPTrackerOption func(*RTPTracker)
func WithVideoEncoders(codecs ...codec.VideoEncoderBuilder) func(*RTPTracker) {
return func(tracker *RTPTracker) {
tracker.videoEncoders = codecs
}
}
func WithAudioEncoders(codecs ...codec.AudioEncoderBuilder) func(*RTPTracker) {
return func(tracker *RTPTracker) {
tracker.audioEncoders = codecs
}
}
func NewRTPTracker(opts ...RTPTrackerOption) *RTPTracker {
var tracker RTPTracker
for _, opt := range opts {
opt(&tracker)
}
return &tracker
}
func (tracker *RTPTracker) Track(track Track) *RTPTrack {
rtpTrack := RTPTrack{
Track: track,
}
return &rtpTrack
}
type RTPTrack struct {
Track
tracker *RTPTracker
currentEncoder codec.ReadCloser
currentParams RTPParameters
lastProp prop.Media
}
func (track *RTPTrack) SetParameters(params RTPParameters) error {
var err error
switch t := track.Track.(type) {
case *VideoTrack:
err = track.setParametersVideo(t, &params)
case *AudioTrack:
err = track.setParametersAudio(t, &params)
default:
err = fmt.Errorf("unsupported track type")
}
if err == nil {
track.currentParams = params
}
return err
}
func (track *RTPTrack) setParametersVideo(videoTrack *VideoTrack, params *RTPParameters) error {
if params.SelectedCodec.Type != webrtc.RTPCodecTypeVideo {
return fmt.Errorf("invalid selected RTP codec type. Expected video but got audio")
}
video.DetectChanges(interval time.Duration, onChange func(prop.Media))
return nil
}
func (track *RTPTrack) setParametersAudio(audioTrack *AudioTrack, params *RTPParameters) error {
return nil
}
func (track *RTPTrack) ReadRTP() (*rtp.Packet, error) {
if track.currentEncoder == nil {
return nil, fmt.Errorf("Encoder has not been specified. Please call SetParameters to specify.")
}
return nil, nil
}
func (track *RTPTrack) WriteRTCP(packet rtcp.Packet) error {
return nil
}

View File

@@ -3,7 +3,6 @@ package mediadevices
import (
"fmt"
"image"
"math/rand"
"sync"
"github.com/pion/mediadevices/pkg/driver"
@@ -24,7 +23,6 @@ const (
// Reference: https://w3c.github.io/mediacapture-main/#mediastreamtrack
type Track interface {
ID() string
SSRC() uint32
Kind() TrackKind
Stop()
// OnEnded registers a handler to receive an error from the media stream track.
@@ -197,7 +195,6 @@ func (track *AudioTrack) Transform(fns ...audio.TransformFunc) {
type baseTrack struct {
d driver.Driver
constraints MediaTrackConstraints
ssrc uint32
onErrorHandler func(error)
err error
@@ -206,17 +203,13 @@ type baseTrack struct {
}
func newBaseTrack(d driver.Driver, constraints MediaTrackConstraints) baseTrack {
return baseTrack{d: d, constraints: constraints, ssrc: rand.Uint32()}
return baseTrack{d: d, constraints: constraints}
}
func (t *baseTrack) ID() string {
return t.d.ID()
}
func (t *baseTrack) SSRC() uint32 {
return t.ssrc
}
// OnEnded sets an error handler. When a track has been created and started, if an
// error occurs, handler will get called with the error given to the parameter.
func (t *baseTrack) OnEnded(handler func(error)) {

View File

@@ -1,43 +1,45 @@
package mediadevices
import (
"github.com/pion/mediadevices/pkg/codec"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/webrtc/v2"
)
// PeerConnection is an extension of webrtc.PeerConnection which allows to operate with raw video/audio
type PeerConnection struct {
*webrtc.PeerConnection
audioEncoders []codec.AudioEncoderBuilder
videoEncoders []codec.VideoEncoderBuilder
// == WebRTC v3 design ==
// Reader is an interface to handle incoming RTP stream.
type Reader interface {
ReadRTP() (*rtp.Packet, error)
WriteRTCP(rtcp.Packet) error
}
// PeerConnectionOption is a function that configures the underlying PeerConnection
type PeerConnectionOption func(*PeerConnection)
func WithVideoEncoders(encoders ...codec.VideoEncoderBuilder) PeerConnectionOption {
return PeerConnectionOption(func(pc *PeerConnection) {
pc.videoEncoders = encoders
})
// TrackBase represents common MediaStreamTrack functionality of LocalTrack and RemoteTrack.
type TrackBase interface {
ID() string
}
func WithAudioEncoders(encoders ...codec.AudioEncoderBuilder) PeerConnectionOption {
return PeerConnectionOption(func(pc *PeerConnection) {
pc.audioEncoders = encoders
})
type LocalRTPTrack interface {
TrackBase
Reader
// SetParameters sets information about how the data is to be encoded.
// This will be called by PeerConnection according to the result of
// SDP based negotiation.
// It will be called via RTPSender.Parameters() by PeerConnection to
// tell the negotiated media codec information.
//
// This is pion's extension to process data without having encoder/decoder
// in webrtc package.
SetParameters(RTPParameters) error
}
func ExtendPeerConnection(pc *webrtc.PeerConnection, opts ...PeerConnectionOption) (*PeerConnection, error) {
extPC := PeerConnection{
PeerConnection: pc,
}
for _, opt := range opts {
opt(&extPC)
}
return &extPC, nil
}
func (pc *PeerConnection) ExtAddTransceiverFromTrack(track Track, init ...webrtc.RtpTransceiverInit) (*webrtc.RTPTransceiver, error) {
// RTPParameters represents RTCRtpParameters which contains information about
// how the RTC data is to be encoded/decoded.
//
// ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpSendParameters
type RTPParameters struct {
SSRC uint32
SelectedCodec *webrtc.RTPCodec
Codecs []*webrtc.RTPCodec
}