mirror of
https://github.com/pion/mediadevices.git
synced 2026-04-22 15:57:27 +08:00
Allow to use user defined Track
Add WithTrackGenerator option to specify TrackGenerator. This allows user to replace Track by user defined one that has WriteSample() and Codec() interface.
This commit is contained in:
committed by
Lukas Herman
parent
99af57a42a
commit
bca254261d
+39
-8
@@ -20,7 +20,7 @@ type MediaDevices interface {
|
||||
// NewMediaDevices creates MediaDevices interface that provides access to connected media input devices
|
||||
// like cameras and microphones, as well as screen sharing.
|
||||
// In essence, it lets you obtain access to any hardware source of media data.
|
||||
func NewMediaDevices(pc *webrtc.PeerConnection) MediaDevices {
|
||||
func NewMediaDevices(pc *webrtc.PeerConnection, opts ...MediaDevicesOption) MediaDevices {
|
||||
codecs := make(map[webrtc.RTPCodecType][]*webrtc.RTPCodec)
|
||||
for _, kind := range []webrtc.RTPCodecType{
|
||||
webrtc.RTPCodecTypeAudio,
|
||||
@@ -28,20 +28,51 @@ func NewMediaDevices(pc *webrtc.PeerConnection) MediaDevices {
|
||||
} {
|
||||
codecs[kind] = pc.GetRegisteredRTPCodecs(kind)
|
||||
}
|
||||
|
||||
return &mediaDevices{codecs}
|
||||
return NewMediaDevicesFromCodecs(codecs, opts...)
|
||||
}
|
||||
|
||||
// NewMediaDevicesFromCodecs creates MediaDevices interface from lists of the available codecs
|
||||
// that provides access to connected media input devices like cameras and microphones,
|
||||
// as well as screen sharing.
|
||||
// In essence, it lets you obtain access to any hardware source of media data.
|
||||
func NewMediaDevicesFromCodecs(codecs map[webrtc.RTPCodecType][]*webrtc.RTPCodec) MediaDevices {
|
||||
return &mediaDevices{codecs}
|
||||
func NewMediaDevicesFromCodecs(codecs map[webrtc.RTPCodecType][]*webrtc.RTPCodec, opts ...MediaDevicesOption) MediaDevices {
|
||||
mdo := MediaDevicesOptions{
|
||||
codecs: codecs,
|
||||
trackGenerator: defaultTrackGenerator,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(&mdo)
|
||||
}
|
||||
return &mediaDevices{
|
||||
MediaDevicesOptions: mdo,
|
||||
}
|
||||
}
|
||||
|
||||
// TrackGenerator is a function to create new track.
|
||||
type TrackGenerator func(payloadType uint8, ssrc uint32, id, label string, codec *webrtc.RTPCodec) (LocalTrack, error)
|
||||
|
||||
var defaultTrackGenerator = TrackGenerator(func(pt uint8, ssrc uint32, id, label string, codec *webrtc.RTPCodec) (LocalTrack, error) {
|
||||
return webrtc.NewTrack(pt, ssrc, id, label, codec)
|
||||
})
|
||||
|
||||
type mediaDevices struct {
|
||||
codecs map[webrtc.RTPCodecType][]*webrtc.RTPCodec
|
||||
MediaDevicesOptions
|
||||
}
|
||||
|
||||
// MediaDevicesOptions stores parameters used by MediaDevices.
|
||||
type MediaDevicesOptions struct {
|
||||
codecs map[webrtc.RTPCodecType][]*webrtc.RTPCodec
|
||||
trackGenerator TrackGenerator
|
||||
}
|
||||
|
||||
// MediaDevicesOption is a type of MediaDevices functional option.
|
||||
type MediaDevicesOption func(*MediaDevicesOptions)
|
||||
|
||||
// WithTrackGenerator specifies a TrackGenerator to use customized track.
|
||||
func WithTrackGenerator(gen TrackGenerator) MediaDevicesOption {
|
||||
return func(o *MediaDevicesOptions) {
|
||||
o.trackGenerator = gen
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserMedia prompts the user for permission to use a media input which produces a MediaStream
|
||||
@@ -161,7 +192,7 @@ func (m *mediaDevices) selectAudio(constraints MediaTrackConstraints) (Tracker,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newAudioTrack(m.codecs[webrtc.RTPCodecTypeAudio], d, c)
|
||||
return newAudioTrack(&m.MediaDevicesOptions, d, c)
|
||||
}
|
||||
func (m *mediaDevices) selectVideo(constraints MediaTrackConstraints) (Tracker, error) {
|
||||
filter := driver.FilterVideoRecorder()
|
||||
@@ -178,7 +209,7 @@ func (m *mediaDevices) selectVideo(constraints MediaTrackConstraints) (Tracker,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newVideoTrack(m.codecs[webrtc.RTPCodecTypeVideo], d, c)
|
||||
return newVideoTrack(&m.MediaDevicesOptions, d, c)
|
||||
}
|
||||
|
||||
func (m *mediaDevices) EnumerateDevices() []MediaDeviceInfo {
|
||||
|
||||
+2
-3
@@ -3,17 +3,16 @@ package mediadevices
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pion/webrtc/v2"
|
||||
"github.com/pion/webrtc/v2/pkg/media"
|
||||
)
|
||||
|
||||
type sampler struct {
|
||||
track *webrtc.Track
|
||||
track LocalTrack
|
||||
clockRate float64
|
||||
lastTimestamp time.Time
|
||||
}
|
||||
|
||||
func newSampler(track *webrtc.Track) *sampler {
|
||||
func newSampler(track LocalTrack) *sampler {
|
||||
return &sampler{
|
||||
track: track,
|
||||
clockRate: float64(track.Codec().ClockRate),
|
||||
|
||||
@@ -21,14 +21,19 @@ type Tracker interface {
|
||||
OnEnded(func(error))
|
||||
}
|
||||
|
||||
type LocalTrack interface {
|
||||
WriteSample(s media.Sample) error
|
||||
Codec() *webrtc.RTPCodec
|
||||
}
|
||||
|
||||
type track struct {
|
||||
t *webrtc.Track
|
||||
t LocalTrack
|
||||
s *sampler
|
||||
|
||||
onErrorHandler atomic.Value // func(error)
|
||||
}
|
||||
|
||||
func newTrack(codecs []*webrtc.RTPCodec, d driver.Driver, codecName string) (*track, error) {
|
||||
func newTrack(codecs []*webrtc.RTPCodec, trackGenerator TrackGenerator, d driver.Driver, codecName string) (*track, error) {
|
||||
var selectedCodec *webrtc.RTPCodec
|
||||
for _, c := range codecs {
|
||||
if c.Name == codecName {
|
||||
@@ -40,7 +45,7 @@ func newTrack(codecs []*webrtc.RTPCodec, d driver.Driver, codecName string) (*tr
|
||||
return nil, fmt.Errorf("track: %s is not registered in media engine", codecName)
|
||||
}
|
||||
|
||||
t, err := webrtc.NewTrack(
|
||||
t, err := trackGenerator(
|
||||
selectedCodec.PayloadType,
|
||||
rand.Uint32(),
|
||||
d.ID(),
|
||||
@@ -69,7 +74,7 @@ func (t *track) onError(err error) {
|
||||
}
|
||||
|
||||
func (t *track) Track() *webrtc.Track {
|
||||
return t.t
|
||||
return t.t.(*webrtc.Track)
|
||||
}
|
||||
|
||||
type videoTrack struct {
|
||||
@@ -81,9 +86,9 @@ type videoTrack struct {
|
||||
|
||||
var _ Tracker = &videoTrack{}
|
||||
|
||||
func newVideoTrack(codecs []*webrtc.RTPCodec, d driver.Driver, constraints MediaTrackConstraints) (*videoTrack, error) {
|
||||
func newVideoTrack(opts *MediaDevicesOptions, d driver.Driver, constraints MediaTrackConstraints) (*videoTrack, error) {
|
||||
codecName := constraints.CodecName
|
||||
t, err := newTrack(codecs, d, codecName)
|
||||
t, err := newTrack(opts.codecs[webrtc.RTPCodecTypeVideo], opts.trackGenerator, d, codecName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -156,9 +161,9 @@ type audioTrack struct {
|
||||
|
||||
var _ Tracker = &audioTrack{}
|
||||
|
||||
func newAudioTrack(codecs []*webrtc.RTPCodec, d driver.Driver, constraints MediaTrackConstraints) (*audioTrack, error) {
|
||||
func newAudioTrack(opts *MediaDevicesOptions, d driver.Driver, constraints MediaTrackConstraints) (*audioTrack, error) {
|
||||
codecName := constraints.CodecName
|
||||
t, err := newTrack(codecs, d, codecName)
|
||||
t, err := newTrack(opts.codecs[webrtc.RTPCodecTypeAudio], opts.trackGenerator, d, codecName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user