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 }