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 } }