Files
seanime-docker/seanime-2.9.10/internal/mkvparser/metadata.go
2025-09-20 14:08:38 +01:00

117 lines
4.1 KiB
Go

package mkvparser
// TrackType represents the type of a Matroska track.
type TrackType string
const (
TrackTypeVideo TrackType = "video"
TrackTypeAudio TrackType = "audio"
TrackTypeSubtitle TrackType = "subtitle"
TrackTypeLogo TrackType = "logo"
TrackTypeButtons TrackType = "buttons"
TrackTypeComplex TrackType = "complex"
TrackTypeUnknown TrackType = "unknown"
)
type AttachmentType string
const (
AttachmentTypeFont AttachmentType = "font"
AttachmentTypeSubtitle AttachmentType = "subtitle"
AttachmentTypeOther AttachmentType = "other"
)
// TrackInfo holds extracted information about a media track.
type TrackInfo struct {
Number int64 `json:"number"`
UID int64 `json:"uid"`
Type TrackType `json:"type"` // "video", "audio", "subtitle", etc.
CodecID string `json:"codecID"`
Name string `json:"name,omitempty"`
Language string `json:"language,omitempty"` // Best effort language code
LanguageIETF string `json:"languageIETF,omitempty"` // IETF language code
Default bool `json:"default"`
Forced bool `json:"forced"`
Enabled bool `json:"enabled"`
CodecPrivate string `json:"codecPrivate,omitempty"` // Raw CodecPrivate data, often used for subtitle headers (e.g., ASS/SSA styles)
// Video specific
Video *VideoTrack `json:"video,omitempty"`
// Audio specific
Audio *AudioTrack `json:"audio,omitempty"`
// Internal fields
contentEncodings *ContentEncodings `json:"-"`
defaultDuration uint64 `json:"-"` // in ns
}
// ChapterInfo holds extracted information about a chapter.
type ChapterInfo struct {
UID uint64 `json:"uid"`
Start float64 `json:"start"` // Start time in seconds
End float64 `json:"end,omitempty"` // End time in seconds
Text string `json:"text,omitempty"`
Languages []string `json:"languages,omitempty"` // Legacy 3-letter language codes
LanguagesIETF []string `json:"languagesIETF,omitempty"` // IETF language tags
}
// AttachmentInfo holds extracted information about an attachment.
type AttachmentInfo struct {
UID uint64 `json:"uid"`
Filename string `json:"filename"`
Mimetype string `json:"mimetype"`
Size int `json:"size"`
Description string `json:"description,omitempty"`
Type AttachmentType `json:"type,omitempty"`
Data []byte `json:"-"` // Data loaded into memory
IsCompressed bool `json:"-"` // Whether the data is compressed
}
// Metadata holds all extracted metadata.
type Metadata struct {
Title string `json:"title,omitempty"`
Duration float64 `json:"duration"` // Duration in seconds
TimecodeScale float64 `json:"timecodeScale"` // Original timecode scale from Info
MuxingApp string `json:"muxingApp,omitempty"`
WritingApp string `json:"writingApp,omitempty"`
Tracks []*TrackInfo `json:"tracks"`
VideoTracks []*TrackInfo `json:"videoTracks"`
AudioTracks []*TrackInfo `json:"audioTracks"`
SubtitleTracks []*TrackInfo `json:"subtitleTracks"`
Chapters []*ChapterInfo `json:"chapters"`
Attachments []*AttachmentInfo `json:"attachments"`
MimeCodec string `json:"mimeCodec,omitempty"` // RFC 6381 codec string
Error error `json:"-"`
}
func (m *Metadata) GetTrackByNumber(num int64) *TrackInfo {
for _, track := range m.Tracks {
if track.Number == num {
return track
}
}
return nil
}
func (m *Metadata) GetAttachmentByName(name string) (*AttachmentInfo, bool) {
for _, attachment := range m.Attachments {
if attachment.Filename == name {
return attachment, true
}
}
return nil, false
}
///////////////////////////////////////////////////////////////////////////////////////////
func (t *TrackInfo) IsAudioTrack() bool {
return t.Type == TrackTypeAudio
}
func (t *TrackInfo) IsVideoTrack() bool {
return t.Type == TrackTypeVideo
}
func (t *TrackInfo) IsSubtitleTrack() bool {
return t.Type == TrackTypeSubtitle
}