Can now specify different encoding settings to do multiple ones.

master
Zed A. Shaw 1 month ago
parent 1a49aadc8c
commit 6dffeb7e7d
  1. 28
      config.json
  2. 10
      config.toml
  3. 45
      config/settings.go
  4. 64
      main.go

@ -0,0 +1,28 @@
[
{
"Format": "mp4",
"Scale": "1280:720",
"VideoBitrate": 900,
"AudioBitrate": 192,
"Speed": "veryfast",
"CleanFilename": false,
"CRF": 20,
"FPS": 30,
"Tune": "animation",
"Input": "test*.mp4",
"OutDir": "renders"
},
{
"Format": "mp4",
"Scale": "1920:1080",
"VideoBitrate": 1200,
"AudioBitrate": 192,
"Speed": "veryfast",
"CleanFilename": false,
"CRF": 20,
"FPS": 30,
"Tune": "animation",
"Input": "test*.mp4",
"OutDir": "renders"
}
]

@ -1,10 +0,0 @@
Scale = "1280:720"
VideoBitrate = 900
AudioBitrate = 192
Speed = "veryslow"
CleanFilename = false
CRF = 20
FPS = 30
Tune = "animation"
Input = "test*.mp4"
OutDir = "renders"

@ -3,16 +3,11 @@ package config
import (
"flag"
"log"
"github.com/BurntSushi/toml"
"os"
"encoding/json"
)
type config struct {
Test int
TestStart int
Debug int
Progress bool
ConfigPath string
type VideoOpts struct {
Scale string
VideoBitrate int
AudioBitrate int
@ -22,34 +17,40 @@ type config struct {
FPS int
Tune string
Input string
Output string
OutDir string
Test int
TestStart int
}
var Settings config
type Settings struct {
Debug int
Progress bool
ConfigPath string
Encodings []VideoOpts
}
func parseFlags(c *config) {
flag.IntVar(&c.Test, "test", 0, "Make a test video <int> seconds long.")
flag.IntVar(&c.TestStart, "test-start", 60, "When to start the test clip.")
func ParseFlags(c *Settings) {
flag.IntVar(&c.Debug, "debug", 0, "1=print the ffmpeg command, 2=and its stderr output")
flag.BoolVar(&c.Progress, "progress", false, "Show percent progress. Not accurate (thanks ffmpeg)")
flag.StringVar(&c.ConfigPath, "config", "config.toml", "config.toml to load")
flag.StringVar(&c.ConfigPath, "config", "config.json", "config.json to load")
flag.Parse()
}
func Load() {
parseFlags(&Settings)
func Load() Settings {
var config Settings
metadata, err := toml.DecodeFile(Settings.ConfigPath, &Settings)
ParseFlags(&config)
data, err := os.ReadFile(config.ConfigPath)
if err != nil {
log.Fatalf("error loading config.toml: %v", err)
log.Fatalf("error reading config %s: %v", config.ConfigPath, err);
}
bad_keys := metadata.Undecoded()
if len(bad_keys) > 0 {
log.Fatalf("unknown configuration keys: %v", bad_keys);
err = json.Unmarshal(data, &config.Encodings)
if err != nil {
log.Fatalf("error loading %s: %v", config.ConfigPath, err)
}
return config
}

@ -26,40 +26,40 @@ func ModFile(fname string, scale string) string {
}
func Run(pass int, pid int, input string, output string) {
func Run(encoding config.VideoOpts, pass int, pid int, input string, output string) {
encode := fluentffmpeg.NewCommand("")
mp4_opts := []string{
"-vf", fmt.Sprintf("scale=%s:flags=lanczos", config.Settings.Scale),
"-aspect", config.Settings.Scale,
mp4_encoding := []string{
"-vf", fmt.Sprintf("scale=%s:flags=lanczos", encoding.Scale),
"-aspect", encoding.Scale,
"-pix_fmt", "yuv420p",
"-tune", config.Settings.Tune,
"-tune", encoding.Tune,
"-movflags", "faststart",
"-pass", fmt.Sprint(pass),
"-passlogfile", fmt.Sprintf("ffmpeg2pass-%x.log", pid),
"-preset", config.Settings.Speed,
"-preset", encoding.Speed,
}
if pass != 3 {
mp4_opts = append(mp4_opts, "-an")
mp4_encoding = append(mp4_encoding, "-an")
} else {
encode.AudioCodec("aac")
mp4_opts = append(mp4_opts,
"-b:a", fmt.Sprint(config.Settings.AudioBitrate * 1024))
mp4_encoding = append(mp4_encoding,
"-b:a", fmt.Sprint(encoding.AudioBitrate * 1024))
}
if config.Settings.Test > 0 {
if encoding.Test > 0 {
encode.InputOptions(
"-ss", fmt.Sprintf("00:%d", config.Settings.TestStart))
mp4_opts = append(mp4_opts, "-t", fmt.Sprint(config.Settings.Test))
"-ss", fmt.Sprintf("00:%d", encoding.TestStart))
mp4_encoding = append(mp4_encoding, "-t", fmt.Sprint(encoding.Test))
}
encode.VideoCodec("libx264").
VideoBitRate(config.Settings.VideoBitrate * 1024).
FrameRate(config.Settings.FPS).
ConstantRateFactor(config.Settings.CRF)
VideoBitRate(encoding.VideoBitrate * 1024).
FrameRate(encoding.FPS).
ConstantRateFactor(encoding.CRF)
encode.OutputOptions(mp4_opts...)
encode.OutputOptions(mp4_encoding...)
cmd := encode.InputPath(input).
OutputFormat("mp4").
@ -80,26 +80,26 @@ func DevNull() string {
}
}
func RenderFile(pid int, path string, target string) {
Run(1, pid, path, DevNull())
Run(2, pid, path, DevNull())
Run(3, pid, path, target)
func RenderFile(opts config.VideoOpts, pid int, path string, target string) {
Run(opts, 1, pid, path, DevNull())
Run(opts, 2, pid, path, DevNull())
Run(opts, 3, pid, path, target)
}
func RenderToDir() {
matches, err := filepath.Glob(config.Settings.Input)
func RenderToDir(encoding config.VideoOpts) {
matches, err := filepath.Glob(encoding.Input)
if err != nil { log.Fatalf("%v", err) }
for _, path := range matches {
base := filepath.Base(path)
target := filepath.Join(config.Settings.OutDir, base)
target = ModFile(target, config.Settings.Scale)
target := filepath.Join(encoding.OutDir, base)
target = ModFile(target, encoding.Scale)
_, err := os.Stat(target)
if err != nil {
fmt.Println("--- PATH", path, "->", target)
RenderFile(rand.Int(), path, target)
RenderFile(encoding, rand.Int(), path, target)
} else {
fmt.Println("^^^ SKIP", path, "->", target)
}
@ -107,13 +107,13 @@ func RenderToDir() {
}
func main() {
config.Load()
settings := config.Load()
if config.Settings.Output != "" {
RenderFile(rand.Int(), config.Settings.Input, config.Settings.Output)
} else if config.Settings.OutDir != "" {
RenderToDir()
} else {
log.Fatal("config file needs either Output or OutDir")
for _, encoding := range settings.Encodings {
if encoding.OutDir != "" {
RenderToDir(encoding)
} else {
log.Fatal("config file needs either Output or OutDir")
}
}
}

Loading…
Cancel
Save