diff --git a/av/codec/frame.go b/av/codec/frame.go index 144d133..5943d37 100644 --- a/av/codec/frame.go +++ b/av/codec/frame.go @@ -4,15 +4,77 @@ package codec -// 帧类型 -const ( - FrameVideo = byte(iota) - FrameAudio +import ( + "fmt" + "strings" ) +// MediaType 媒体类型 +type MediaType int + +// 媒体类型常量 +const ( + MediaTypeUnknown MediaType = iota - 1 // Usually treated as MediaTypeData + MediaTypeVideo + MediaTypeAudio + MediaTypeData // Opaque data information usually continuous + MediaTypeSubtitle + MediaTypeAttachment // Opaque data information usually sparse + MediaTypeNB +) + +// String returns a lower-case ASCII representation of the media type. +func (mt MediaType) String() string { + switch mt { + case MediaTypeVideo: + return "video" + case MediaTypeAudio: + return "audio" + case MediaTypeData: + return "data" + case MediaTypeSubtitle: + return "subtitle" + case MediaTypeAttachment: + return "attachment" + default: + return "" + } +} + +// MarshalText marshals the MediaType to text. +func (mt *MediaType) MarshalText() ([]byte, error) { + return []byte(mt.String()), nil +} + +// UnmarshalText unmarshals text to a MediaType. +func (mt *MediaType) UnmarshalText(text []byte) error { + if !mt.unmarshalText(string(text)) { + return fmt.Errorf("unrecognized media type: %q", text) + } + return nil +} + +func (mt *MediaType) unmarshalText(text string) bool { + switch strings.ToLower(text) { + case "video": + *mt = MediaTypeVideo + case "audio": + *mt = MediaTypeAudio + case "data": + *mt = MediaTypeData + case "subtitle": + *mt = MediaTypeSubtitle + case "attachment": + *mt = MediaTypeAttachment + default: + return false + } + return true +} + // Frame 音视频完整帧 type Frame struct { - FrameType byte // 帧类型 + MediaType // 媒体类型 AbsTimestamp int64 // 绝对时间戳(主要用于表示 pts),单位为 ms 的 UNIX 时间 Payload []byte // 媒体数据载荷 } diff --git a/av/codec/metadata.go b/av/codec/metadata.go index 04a199d..d9e3f6b 100644 --- a/av/codec/metadata.go +++ b/av/codec/metadata.go @@ -6,14 +6,16 @@ package codec // VideoMeta 视频元数据 type VideoMeta struct { - Codec string `json:"codec"` - Width int `json:"width,omitempty"` - Height int `json:"height,omitempty"` - FrameRate float64 `json:"framerate,omitempty"` - DataRate float64 `json:"datarate,omitempty"` - Sps []byte `json:"-"` - Pps []byte `json:"-"` - Vps []byte `json:"-"` + Codec string `json:"codec"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` + FixedFrameRate bool `json:"fixedframerate,omitempty"` + FrameRate float64 `json:"framerate,omitempty"` + DataRate float64 `json:"datarate,omitempty"` + ClockRate int `json:"clockrate,omitempty"` + Sps []byte `json:"-"` + Pps []byte `json:"-"` + Vps []byte `json:"-"` } // AudioMeta 音频元数据 diff --git a/av/format/flv/muxeravcaac.go b/av/format/flv/muxeravcaac.go index 47a6bf9..885ff9a 100644 --- a/av/format/flv/muxeravcaac.go +++ b/av/format/flv/muxeravcaac.go @@ -116,7 +116,7 @@ func (muxer *MuxerAvcAac) process() { muxer.basePts = frame.AbsTimestamp } - if frame.FrameType == codec.FrameVideo { + if frame.MediaType == codec.MediaTypeVideo { if err := muxer.muxVideoTag(frame); err != nil { muxer.logger.Errorf("flvmuxer: muxVideoTag error - %s", err.Error()) } diff --git a/av/format/mpegts/muxeravcaac.go b/av/format/mpegts/muxeravcaac.go index 0bf8d86..8019b32 100644 --- a/av/format/mpegts/muxeravcaac.go +++ b/av/format/mpegts/muxeravcaac.go @@ -131,7 +131,7 @@ func (muxer *MuxerAvcAac) process() { muxer.basePts = frame.AbsTimestamp } - if frame.FrameType == codec.FrameVideo { + if frame.MediaType == codec.MediaTypeVideo { if err := muxer.muxVideoTag(frame); err != nil { muxer.logger.Errorf("tsmuxer: muxVideoFrame error - %s", err.Error()) } diff --git a/av/format/rtp/aac_depacketizer.go b/av/format/rtp/aac_depacketizer.go index eecef99..20b1559 100644 --- a/av/format/rtp/aac_depacketizer.go +++ b/av/format/rtp/aac_depacketizer.go @@ -75,7 +75,7 @@ func (aacdp *aacDepacketizer) depacketizeFor2ByteAUHeader(packet *Packet) (err e auHeader := uint16(0) | (uint16(auHeaders[0]) << 8) | uint16(auHeaders[1]) frameSize := auHeader >> aacdp.indexLength frame := &codec.Frame{ - FrameType: codec.FrameAudio, + MediaType: codec.MediaTypeAudio, AbsTimestamp: aacdp.rtp2ntp(frameTimeStamp), Payload: framesPayload[:frameSize], } @@ -109,7 +109,7 @@ func (aacdp *aacDepacketizer) depacketizeFor1ByteAUHeader(packet *Packet) (err e auHeader := auHeaders[0] frameSize := auHeader >> aacdp.indexLength frame := &codec.Frame{ - FrameType: codec.FrameAudio, + MediaType: codec.MediaTypeAudio, AbsTimestamp: aacdp.rtp2ntp(frameTimeStamp), Payload: framesPayload[:frameSize], } diff --git a/av/format/rtp/demuxer_test.go b/av/format/rtp/demuxer_test.go index d168c55..7048684 100644 --- a/av/format/rtp/demuxer_test.go +++ b/av/format/rtp/demuxer_test.go @@ -77,7 +77,7 @@ type frameWriter struct { } func (fw *frameWriter) WriteFrame(frame *codec.Frame) (err error) { - if frame.FrameType == codec.FrameVideo { + if frame.MediaType == codec.MediaTypeVideo { fw.videoFrames++ if h264.IsSps(frame.Payload[0]) { fw.sps++ diff --git a/av/format/rtp/h264_depacketizer.go b/av/format/rtp/h264_depacketizer.go index 83d455e..f0e7242 100644 --- a/av/format/rtp/h264_depacketizer.go +++ b/av/format/rtp/h264_depacketizer.go @@ -67,7 +67,7 @@ func (h264dp *h264Depacketizer) Depacketize(packet *Packet) (err error) { return } frame := &codec.Frame{ - FrameType: codec.FrameVideo, + MediaType: codec.MediaTypeVideo, AbsTimestamp: h264dp.rtp2ntp(packet.Timestamp), Payload: payload, } @@ -113,7 +113,7 @@ func (h264dp *h264Depacketizer) depacketizeStapa(packet *Packet) (err error) { off += 2 if payload[off]&0x1f != h264.NalFillerData { frame := &codec.Frame{ - FrameType: codec.FrameVideo, + MediaType: codec.MediaTypeVideo, AbsTimestamp: h264dp.rtp2ntp(packet.Timestamp), Payload: make([]byte, nalSize), } @@ -176,7 +176,7 @@ func (h264dp *h264Depacketizer) depacketizeFuA(packet *Packet) (err error) { } frame := &codec.Frame{ - FrameType: codec.FrameVideo, + MediaType: codec.MediaTypeVideo, AbsTimestamp: h264dp.rtp2ntp(packet.Timestamp), Payload: make([]byte, frameLen)}