goffmpeg/pkg/ffmpeg/stream/mediaInfo.go

84 lines
2.0 KiB
Go

package stream
import (
"time"
"git.kingecg.top/kingecg/goffmpeg/pkg/ffmpeg"
)
// MediaInfo represents media stream information
type MediaInfo struct {
Duration time.Duration
StartTime time.Duration
BitRate int64
Format string
FormatLong string
Streams []*StreamInfo
}
// StreamInfo represents a single stream's information
type StreamInfo struct {
Index int
Type ffmpeg.CodecType
CodecName string
CodecLongName string
Width int // video only
Height int // video only
PixelFormat string // video only
SampleRate int // audio only
Channels int // audio only
ChannelLayout string // audio only
FrameSize int
TimeBase ffmpeg.Rational
BitRate int64
}
// NewMediaInfo creates MediaInfo from FormatContext
func NewMediaInfo(fc *ffmpeg.FormatContext) (*MediaInfo, error) {
if fc == nil {
return nil, nil
}
info := &MediaInfo{
Streams: make([]*StreamInfo, 0),
}
// Get format info
info.Duration = time.Duration(fc.Duration()) * time.Microsecond / 1000
info.StartTime = time.Duration(fc.StartTime()) * time.Microsecond / 1000
info.BitRate = fc.BitRate()
// Get streams info
streams := fc.Streams()
for _, s := range streams {
si := &StreamInfo{
Index: s.Index(),
Type: s.Type(),
TimeBase: s.TimeBase(),
}
cp := s.CodecParameters()
if cp != nil {
si.CodecName = codecIDToName(cp.CodecID())
si.CodecLongName = codecIDToLongName(cp.CodecID())
si.BitRate = cp.BitRate()
si.FrameSize = cp.FrameSize()
switch si.Type {
case ffmpeg.CodecTypeVideo:
si.Width = cp.Width()
si.Height = cp.Height()
si.PixelFormat = pixelFormatToString(cp.Format())
case ffmpeg.CodecTypeAudio:
si.SampleRate = cp.SampleRate()
si.Channels = cp.Channels()
si.ChannelLayout = channelLayoutToString(cp.ChannelLayout())
}
}
info.Streams = append(info.Streams, si)
}
return info, nil
}