217 lines
4.3 KiB
Go
217 lines
4.3 KiB
Go
package extension
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
// CodecId 媒体编解码类型
|
|
type CodecId int
|
|
|
|
const (
|
|
CodecH264 CodecId = iota + 96
|
|
CodecH265
|
|
CodecAAC
|
|
CodecG711A
|
|
CodecG711U
|
|
CodecOpus
|
|
)
|
|
|
|
// Track 媒体通道描述接口
|
|
type Track interface {
|
|
Ready() bool
|
|
Clone() Track
|
|
GetSdp(payloadType uint8) *Sdp
|
|
GetBitRate() int
|
|
SetBitRate(bitRate int)
|
|
GetCodecId() CodecId
|
|
GetExtraData() []byte
|
|
SetExtraData(data []byte)
|
|
}
|
|
|
|
// BaseTrack 实现Track的公共方法
|
|
type BaseTrack struct {
|
|
mutex sync.Mutex
|
|
bitRate int
|
|
codecId CodecId
|
|
extraData []byte
|
|
}
|
|
|
|
func (b *BaseTrack) GetBitRate() int {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
return b.bitRate
|
|
}
|
|
|
|
func (b *BaseTrack) SetBitRate(bitRate int) {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
b.bitRate = bitRate
|
|
}
|
|
|
|
func (b *BaseTrack) GetCodecId() CodecId {
|
|
return b.codecId
|
|
}
|
|
|
|
func (b *BaseTrack) GetExtraData() []byte {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
return b.extraData
|
|
}
|
|
|
|
func (b *BaseTrack) SetExtraData(data []byte) {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
b.extraData = data
|
|
}
|
|
|
|
// VideoTrack 视频轨道接口
|
|
type VideoTrack interface {
|
|
Track
|
|
GetVideoWidth() int
|
|
GetVideoHeight() int
|
|
GetVideoFps() float32
|
|
GetConfigFrames() []Frame
|
|
}
|
|
|
|
// VideoTrackImp 视频轨道具体实现
|
|
type VideoTrackImp struct {
|
|
BaseTrack
|
|
width int
|
|
height int
|
|
fps float32
|
|
}
|
|
|
|
// NewVideoTrackImp 创建视频轨道实例
|
|
func NewVideoTrackImp(codecId CodecId, width, height, fps int) *VideoTrackImp {
|
|
return &VideoTrackImp{
|
|
BaseTrack: BaseTrack{codecId: codecId},
|
|
width: width,
|
|
height: height,
|
|
fps: float32(fps),
|
|
}
|
|
}
|
|
|
|
func (v *VideoTrackImp) Ready() bool {
|
|
return true
|
|
}
|
|
|
|
func (v *VideoTrackImp) Clone() Track {
|
|
v.mutex.Lock()
|
|
defer v.mutex.Unlock()
|
|
return &VideoTrackImp{
|
|
BaseTrack: BaseTrack{
|
|
bitRate: v.bitRate,
|
|
codecId: v.codecId,
|
|
extraData: v.extraData,
|
|
},
|
|
width: v.width,
|
|
height: v.height,
|
|
fps: v.fps,
|
|
}
|
|
}
|
|
|
|
func (v *VideoTrackImp) GetSdp(payloadType uint8) *Sdp {
|
|
// 实际实现应生成SDP描述
|
|
return NewDefaultSdp(payloadType, v)
|
|
}
|
|
|
|
func (v *VideoTrackImp) GetVideoWidth() int {
|
|
return v.width
|
|
}
|
|
|
|
func (v *VideoTrackImp) GetVideoHeight() int {
|
|
return v.height
|
|
}
|
|
|
|
func (v *VideoTrackImp) GetVideoFps() float32 {
|
|
return v.fps
|
|
}
|
|
|
|
func (v *VideoTrackImp) GetConfigFrames() []Frame {
|
|
// 根据编解码器返回sps/pps等配置帧
|
|
return nil
|
|
}
|
|
|
|
// AudioTrack 音频轨道接口
|
|
type AudioTrack interface {
|
|
Track
|
|
GetAudioSampleRate() int
|
|
GetAudioSampleBit() int
|
|
GetAudioChannel() int
|
|
}
|
|
|
|
// AudioTrackImp 音频轨道具体实现
|
|
type AudioTrackImp struct {
|
|
BaseTrack
|
|
sampleRate int
|
|
channels int
|
|
sampleBit int
|
|
}
|
|
|
|
// NewAudioTrackImp 创建音频轨道实例
|
|
func NewAudioTrackImp(codecId CodecId, sampleRate, channels, sampleBit int) *AudioTrackImp {
|
|
return &AudioTrackImp{
|
|
BaseTrack: BaseTrack{codecId: codecId},
|
|
sampleRate: sampleRate,
|
|
channels: channels,
|
|
sampleBit: sampleBit,
|
|
}
|
|
}
|
|
|
|
func (a *AudioTrackImp) Ready() bool {
|
|
return true
|
|
}
|
|
|
|
func (a *AudioTrackImp) Clone() Track {
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
return &AudioTrackImp{
|
|
BaseTrack: BaseTrack{
|
|
bitRate: a.bitRate,
|
|
codecId: a.codecId,
|
|
extraData: a.extraData,
|
|
},
|
|
sampleRate: a.sampleRate,
|
|
channels: a.channels,
|
|
sampleBit: a.sampleBit,
|
|
}
|
|
}
|
|
|
|
func (a *AudioTrackImp) GetSdp(payloadType uint8) *Sdp {
|
|
return NewDefaultSdp(payloadType, a)
|
|
}
|
|
|
|
func (a *AudioTrackImp) GetAudioSampleRate() int {
|
|
if a.sampleRate != 0 {
|
|
return a.sampleRate
|
|
}
|
|
return GetClockRateByCodec(a.codecId)
|
|
}
|
|
|
|
func (a *AudioTrackImp) GetAudioSampleBit() int {
|
|
if a.sampleBit != 0 {
|
|
return a.sampleBit
|
|
}
|
|
return 16
|
|
}
|
|
|
|
func (a *AudioTrackImp) GetAudioChannel() int {
|
|
if a.channels != 0 {
|
|
return a.channels
|
|
}
|
|
return 1
|
|
}
|
|
|
|
// 辅助函数
|
|
func GetClockRateByCodec(codecId CodecId) int {
|
|
switch codecId {
|
|
case CodecAAC:
|
|
return 44100
|
|
case CodecG711A, CodecG711U:
|
|
return 8000
|
|
case CodecOpus:
|
|
return 48000
|
|
default:
|
|
return 0
|
|
}
|
|
} |