wtff

package module
v0.0.0-...-c8d7acd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2024 License: MIT Imports: 17 Imported by: 0

README

wtff is a frontend for some ffmpeg operations. ffmpeg is really neat and powerfull, but some incatations of the CLI are obscure enough that I can never be quite sure if it will do what I want to do, or will spawn a demon from the darkest depths of hell. Who knows? It's possible.

It's not intended to be a flexible tool to solve every problem; just some common things for common usage. Basically: stuff I wanted to do with ffmpeg at some point, with a bit of work to make it slightly generic.

Install with:

go install zgo.at/wtff/cmd/wtff@latest

Commands ("wtff" or "wtff help" for more info):

info         Show file information.
meta         Edit metadata in $EDITOR
mb           Load metadata from MusicBrainz
cat          Join one or more files.
cut          Cut a part from a file.
sub add      Add subtitle.
sub rm       Remove subtitle.
sub save     Save subtitle to file.
sub print    Print subtitle to stdout.
audio add    Add audio track.
audio rm     Remove audio track
audio save   Save audio track to file.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ShowFFCmd = false

Print all ffmpeg commands to stderr

Functions

func AudioAdd

func AudioAdd(ctx context.Context, input, audioFile, lang, title string) error

func AudioRm

func AudioRm(ctx context.Context, input, stream string) error

func AudioSave

func AudioSave(ctx context.Context, input, stream, output string) error

func Cat

func Cat(ctx context.Context, output string, input ...string) error

Cat all files to the output, without re-encoding.

func Cut

func Cut(ctx context.Context, input, output string, start, stop Time) error

Cut a part and write to output.

func SubAdd

func SubAdd(ctx context.Context, input, subFile, lang string) error

func SubRm

func SubRm(ctx context.Context, input, stream string) error

func SubSave

func SubSave(ctx context.Context, input, stream, output string, overwrite bool) error

func WriteMeta

func WriteMeta(ctx context.Context, m Meta, input, output string) error

Types

type Byte

type Byte float64

func (Byte) String

func (b Byte) String() string

func (*Byte) UnmarshalText

func (b *Byte) UnmarshalText(in []byte) error

TODO: finish and move to zstd (it's enough for our purpose here).

type Chapter

type Chapter struct {
	Id        int            `json:"id,omitempty"`         // -1349333221,
	TimeBase  string         `json:"time_base,omitempty"`  // "1/1000000000",
	Start     int            `json:"start,omitempty"`      // 0,
	StartTime Time           `json:"start_time,omitempty"` // "0.000000",
	End       uint           `json:"end,omitempty"`        // 335400000000,
	EndTime   Time           `json:"end_time,omitempty"`   // "335.400000",
	Tags      map[string]any `json:"tags,omitempty"`       // {"title": "Chapter 01"}
}

type Chapters

type Chapters []Chapter

type Format

type Format struct {
	Filename       string         `json:"filename,omitempty"`         // "01.01 Snooper Force.mkv"
	NbStreams      uint           `json:"nb_streams,omitempty"`       // 3
	NbPrograms     uint           `json:"nb_programs,omitempty"`      // 0
	FormatName     string         `json:"format_name,omitempty"`      // "matroska,webm"
	FormatLongName string         `json:"format_long_name,omitempty"` // "Matroska / WebM"
	StartTime      Time           `json:"start_time,omitempty"`       // "0.000000"
	Duration       Time           `json:"duration,omitempty"`         // "1746.601000"
	Size           Byte           `json:"size,omitempty"`             // "324196219"
	BitRate        string         `json:"bit_rate,omitempty"`         // "1484924"
	ProbeScore     uint           `json:"probe_score,omitempty"`      // 100
	Tags           map[string]any `json:"tags,omitempty"`
}

type Meta

type Meta struct {
	Comment          string            `toml:"-"`
	MajorBrand       string            `toml:"-"`
	MinorVersion     string            `toml:"-"`
	CompatibleBrands string            `toml:"-"`
	Encoder          string            `toml:"-"`
	Title            string            `toml:"title"`
	Artist           string            `toml:"artist"`
	Date             string            `toml:"date"`
	Chapters         []MetaChapter     `toml:"chapters"`
	Other            map[string]string `toml:"other"`
}

func ParseMeta

func ParseMeta(input string) (Meta, error)

func ParseMetaFromTOML

func ParseMetaFromTOML(input string) (Meta, error)

func ReadMeta

func ReadMeta(ctx context.Context, input string) (Meta, error)

func (Meta) IsZero

func (m Meta) IsZero() bool

func (Meta) IsZeroExceptChapters

func (m Meta) IsZeroExceptChapters() bool

func (Meta) String

func (m Meta) String() string

func (Meta) TOML

func (m Meta) TOML() string

type MetaChapter

type MetaChapter struct {
	Timebase  [2]int64 `toml:"-"`
	Start     int64    `toml:"-"`
	End       int64    `toml:"-"`
	Title     string   `toml:"title"`
	TOMLStart string   `toml:"start"`
}

func (MetaChapter) StartSecs

func (m MetaChapter) StartSecs() int

type ProbeFile

type ProbeFile struct {
	Format   Format   `json:"format"`
	Streams  Streams  `json:"streams"`
	Chapters Chapters `json:"chapters"`
}

func Probe

func Probe(ctx context.Context, file string) (ProbeFile, error)

Probe gets an overview of streams for this file.

func (ProbeFile) String

func (p ProbeFile) String() string

type Stream

type Stream struct {
	Index              int    `json:"index,omitempty"`                // 0
	CodecName          string `json:"codec_name,omitempty"`           // "hevc"
	CodecLongName      string `json:"codec_long_name,omitempty"`      // "H.265 / HEVC (High Efficiency Video Coding)"
	Profile            string `json:"profile,omitempty"`              // "Main 10"
	CodecType          string `json:"codec_type,omitempty"`           // "video"
	CodecTagString     string `json:"codec_tag_string,omitempty"`     // "[0][0][0][0]"
	CodecTag           string `json:"codec_tag,omitempty"`            // "0x0000"
	Width              uint   `json:"width,omitempty"`                // 720
	Height             uint   `json:"height,omitempty"`               // 568
	CodedWidth         uint   `json:"coded_width,omitempty"`          // 720
	CodedHeight        uint   `json:"coded_height,omitempty"`         // 568
	ClosedCaptions     uint   `json:"closed_captions,omitempty"`      // 0
	HasBFrames         uint   `json:"has_b_frames,omitempty"`         // 2
	SampleAspectRatio  string `json:"sample_aspect_ratio,omitempty"`  // "349:240"
	DisplayAspectRatio string `json:"display_aspect_ratio,omitempty"` // "1047:568"
	PixFmt             string `json:"pix_fmt,omitempty"`              // "yuv420p10le"
	Level              int    `json:"level,omitempty"`                // 90, -99?
	ColorRange         string `json:"color_range,omitempty"`          // "tv"
	ChromaLocation     string `json:"chroma_location,omitempty"`      // "left"
	Refs               uint   `json:"refs,omitempty"`                 // 1
	RFrameRate         string `json:"r_frame_rate,omitempty"`         // "25/1"
	AvgFrameRate       string `json:"avg_frame_rate,omitempty"`       // "25/1"
	TimeBase           string `json:"time_base,omitempty"`            // "1/1000"
	StartPts           uint   `json:"start_pts,omitempty"`            // 80
	StartTime          string `json:"start_time,omitempty"`           // "0.080000"

	SampleFmt     string `json:"sample_fmt,omitempty"`      // "fltp"
	SampleRate    string `json:"sample_rate,omitempty"`     // "48000"
	Channels      uint   `json:"channels,omitempty"`        // 2
	ChannelLayout string `json:"channel_layout,omitempty"`  // "stereo"
	BitsPerSample uint   `json:"bits_per_sample,omitempty"` // 0

	BitRate    string `json:"bit_rate,omitempty"`    // "2498735"
	DurationTs uint   `json:"duration_ts,omitempty"` // 1746601
	Duration   Time   `json:"duration,omitempty"`    // "1746.601000"

	Disposition struct {
		Default         uint `json:"default,omitempty"`
		Dub             uint `json:"dub,omitempty"`
		Original        uint `json:"original,omitempty"`
		Comment         uint `json:"comment,omitempty"`
		Lyrics          uint `json:"lyrics,omitempty"`
		Karaoke         uint `json:"karaoke,omitempty"`
		Forced          uint `json:"forced,omitempty"`
		HearingImpaired uint `json:"hearing_impaired,omitempty"`
		VisualImpaired  uint `json:"visual_impaired,omitempty"`
		CleanEffects    uint `json:"clean_effects,omitempty"`
		AttachedPic     uint `json:"attached_pic,omitempty"`
		TimedThumbnails uint `json:"timed_thumbnails,omitempty"`
	} `json:"disposition,omitempty"`
	Tags map[string]any `json:"tags,omitempty"`
}

func (Stream) Audio

func (s Stream) Audio() bool

func (Stream) Subtitle

func (s Stream) Subtitle() bool

func (Stream) Video

func (s Stream) Video() bool

type Streams

type Streams []Stream

func (Streams) Find

func (s Streams) Find(kind, langOrNum string) int

type SubLine

type SubLine struct {
	Seq   int
	Start time.Time
	End   time.Time
	Text  []string
}

func (SubLine) String

func (s SubLine) String() string

type Subs

type Subs []SubLine

func ParseSRT

func ParseSRT(s string) (Subs, error)

func (Subs) String

func (s Subs) String() string

type Time

type Time struct{ time.Duration }

func (Time) MarshalText

func (t Time) MarshalText() ([]byte, error)

func (Time) String

func (t Time) String() string

func (*Time) UnmarshalText

func (t *Time) UnmarshalText(b []byte) error

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL