/
concat.go
67 lines (60 loc) · 1.84 KB
/
concat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package ff
import (
"errors"
"fmt"
"log"
)
type Config struct {
Inputs []string `opts:"mode=arg, min=1, help=inputs are audio files and directories of audio files"`
Output string `help:"Output file (defaults to <input>.m4a)"`
OutputFormat string `help:"When output is 'stdout', output file format determines encoder"`
OutputType string `help:"When output is empty, output file is '<author> - <title>.<output type>'"`
MaxBitrate int `help:"Bitrate in KB/s (when source bitrate is higher)"`
NoStderr bool `help:"Detach stderr"`
Windows bool `help:"ID3 Windows support"`
Debug bool `help:"Show debug output"`
Docker bool `help:"Use docker even if ffmpeg installed locally"`
}
func Concat(c Config) error {
return (&concat{Config: c}).concat()
}
type concat struct {
Config
}
func (c *concat) concat() error {
if len(c.Inputs) == 0 {
return errors.New("No input files provided")
}
count := new(int)
files := mediaFiles{}
for _, path := range c.Inputs {
if err := c.addPath(&files, path, count); err != nil {
return fmt.Errorf("Failed to add path: %s: %s", path, err)
}
}
if len(files) == 0 {
return errors.New("No audio files provided")
}
if err := c.probeMediaFiles(files); err != nil {
return err
}
m, err := newMetadata(c.Config, files)
if err != nil {
return err
}
output, err := c.computeOutput(files, m)
if err != nil {
return err
}
c.logf("Input '%s' by '%s' (#%d tracks, %s total, bitrate %dk -> %dk)\nOutput: '%s'",
m.title, m.author, len(files), m.duration, m.fileBitrate, m.bitrate, output)
return c.ffmpegExec(m, files, output)
}
func (c *concat) logf(format string, args ...interface{}) {
log.Printf("[goff] "+format, args...)
}
func (c *concat) debugf(format string, args ...interface{}) {
if c.Config.Debug {
c.logf("[DEBUG] "+format, args...)
}
}