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