feat(meta): add writing metadata by ffmpeg
parent
8319df6ca3
commit
02e065aac4
@ -0,0 +1,131 @@
|
||||
package ffmpeg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ffmpegBuilder struct {
|
||||
binary string // ffmpeg binary path
|
||||
options map[string]string // global options
|
||||
inputs []*inputBuilder // input options
|
||||
outputs []*outputBuilder // output options
|
||||
}
|
||||
|
||||
func newFFmpegBuilder() *ffmpegBuilder {
|
||||
return &ffmpegBuilder{
|
||||
binary: "ffmpeg",
|
||||
options: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) AddInput(src *inputBuilder) {
|
||||
b.inputs = append(b.inputs, src)
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) AddOutput(dst *outputBuilder) {
|
||||
b.outputs = append(b.outputs, dst)
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) SetBinary(bin string) {
|
||||
b.binary = bin
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) SetFlag(flag string) {
|
||||
b.options[flag] = ""
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) SetOption(name, value string) {
|
||||
b.options[name] = value
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) Args() (args []string) {
|
||||
for name, val := range b.options {
|
||||
args = append(args, "-"+name)
|
||||
if val != "" {
|
||||
args = append(args, val)
|
||||
}
|
||||
}
|
||||
|
||||
for _, input := range b.inputs {
|
||||
args = append(args, input.Args()...)
|
||||
}
|
||||
for _, output := range b.outputs {
|
||||
args = append(args, output.Args()...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (b *ffmpegBuilder) Command(ctx context.Context) *exec.Cmd {
|
||||
bin := "ffmpeg"
|
||||
if b.binary != "" {
|
||||
bin = b.binary
|
||||
}
|
||||
|
||||
return exec.CommandContext(ctx, bin, b.Args()...)
|
||||
}
|
||||
|
||||
// inputBuilder is the builder for ffmpeg input options
|
||||
type inputBuilder struct {
|
||||
path string
|
||||
options map[string][]string
|
||||
}
|
||||
|
||||
func newInputBuilder(path string) *inputBuilder {
|
||||
return &inputBuilder{
|
||||
path: path,
|
||||
options: make(map[string][]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *inputBuilder) AddOption(name, value string) {
|
||||
b.options[name] = append(b.options[name], value)
|
||||
}
|
||||
|
||||
func (b *inputBuilder) Args() (args []string) {
|
||||
for name, values := range b.options {
|
||||
for _, val := range values {
|
||||
args = append(args, "-"+name, val)
|
||||
}
|
||||
}
|
||||
return append(args, "-i", b.path)
|
||||
}
|
||||
|
||||
// outputBuilder is the builder for ffmpeg output options
|
||||
type outputBuilder struct {
|
||||
path string
|
||||
options map[string][]string
|
||||
}
|
||||
|
||||
func newOutputBuilder(path string) *outputBuilder {
|
||||
return &outputBuilder{
|
||||
path: path,
|
||||
options: make(map[string][]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *outputBuilder) AddOption(name, value string) {
|
||||
b.options[name] = append(b.options[name], value)
|
||||
}
|
||||
|
||||
func (b *outputBuilder) Args() (args []string) {
|
||||
for name, values := range b.options {
|
||||
for _, val := range values {
|
||||
args = append(args, "-"+name, val)
|
||||
}
|
||||
}
|
||||
return append(args, b.path)
|
||||
}
|
||||
|
||||
// AddMetadata is the shortcut for adding "metadata" option
|
||||
func (b *outputBuilder) AddMetadata(stream, key, value string) {
|
||||
optVal := strings.TrimSpace(key) + "=" + strings.TrimSpace(value)
|
||||
|
||||
if stream != "" {
|
||||
b.AddOption("metadata:"+stream, optVal)
|
||||
} else {
|
||||
b.AddOption("metadata", optVal)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue