mirror of
https://github.com/cnotch/ipchub.git
synced 2025-09-26 19:41:18 +08:00
update Frame & Metadata
This commit is contained in:
@@ -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 // 媒体数据载荷
|
||||
}
|
||||
|
@@ -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 音频元数据
|
||||
|
@@ -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())
|
||||
}
|
||||
|
@@ -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())
|
||||
}
|
||||
|
@@ -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],
|
||||
}
|
||||
|
@@ -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++
|
||||
|
@@ -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)}
|
||||
|
||||
|
Reference in New Issue
Block a user