@@ -21,9 +21,9 @@ import (
21
21
type Transcoder struct {
22
22
config * Config
23
23
input string
24
- output string
25
- options []string
26
- metadata * Metadata
24
+ output [] string
25
+ options [][] string
26
+ metadata transcoder. Metadata
27
27
inputPipeReader * io.ReadCloser
28
28
outputPipeReader * io.ReadCloser
29
29
inputPipeWriter * io.WriteCloser
@@ -50,16 +50,36 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress,
50
50
}
51
51
52
52
// Get file metadata
53
- _ , err := t .getMetadata ()
53
+ _ , err := t .GetMetadata ()
54
54
if err != nil {
55
55
return nil , err
56
56
}
57
57
58
- // Get executable flags
58
+ // Append input file and standard options
59
59
args := append ([]string {"-i" , t .input }, opts .GetStrArguments ()... )
60
+ outputLength := len (t .output )
61
+ optionsLength := len (t .options )
60
62
61
- // Append output flag
62
- args = append (args , []string {t .output }... )
63
+ if outputLength == 1 && optionsLength == 0 {
64
+ // Just append the 1 output file we've got
65
+ args = append (args , t .output [0 ])
66
+ } else {
67
+ for index , out := range t .output {
68
+ // Get executable flags
69
+ // If we are at the last output file but still have several options, append them all at once
70
+ if index == outputLength - 1 && outputLength < optionsLength {
71
+ for i := index ; i < len (t .options ); i ++ {
72
+ args = append (args , t .options [i ]... )
73
+ }
74
+ // Otherwise just append the current options
75
+ } else {
76
+ args = append (args , t .options [index ]... )
77
+ }
78
+
79
+ // Append output flag
80
+ args = append (args , out )
81
+ }
82
+ }
63
83
64
84
// Initialize command
65
85
cmd := exec .Command (t .config .FfmpegBinPath , args ... )
@@ -106,7 +126,7 @@ func (t *Transcoder) Input(arg string) transcoder.Transcoder {
106
126
107
127
// Output ...
108
128
func (t * Transcoder ) Output (arg string ) transcoder.Transcoder {
109
- t .output = arg
129
+ t .output = append ( t . output , arg )
110
130
return t
111
131
}
112
132
@@ -128,9 +148,15 @@ func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.
128
148
return t
129
149
}
130
150
131
- // WithOptions ...
151
+ // WithOptions Sets the options object
132
152
func (t * Transcoder ) WithOptions (opts transcoder.Options ) transcoder.Transcoder {
133
- t .options = opts .GetStrArguments ()
153
+ t .options = [][]string {opts .GetStrArguments ()}
154
+ return t
155
+ }
156
+
157
+ // WithAdditionalOptions Appends an additional options object
158
+ func (t * Transcoder ) WithAdditionalOptions (opts transcoder.Options ) transcoder.Transcoder {
159
+ t .options = append (t .options , opts .GetStrArguments ())
134
160
return t
135
161
}
136
162
@@ -144,14 +170,29 @@ func (t *Transcoder) validate() error {
144
170
return errors .New ("missing input option" )
145
171
}
146
172
147
- if t .output == "" {
173
+ outputLength := len (t .output )
174
+
175
+ if outputLength == 0 {
148
176
return errors .New ("missing output option" )
149
177
}
150
178
179
+ // length of output files being greater than length of options would produce an invalid ffmpeg command
180
+ // unless there is only 1 output file, which obviously wouldn't be a problem
181
+ if outputLength > len (t .options ) && outputLength != 1 {
182
+ return errors .New ("number of options and output files does not match" )
183
+ }
184
+
185
+ for index , output := range t .output {
186
+ if output == "" {
187
+ return fmt .Errorf ("output at index %d is an empty string" , index )
188
+ }
189
+ }
190
+
151
191
return nil
152
192
}
153
193
154
- func (t * Transcoder ) getMetadata () (metadata * Metadata , err error ) {
194
+ // GetMetadata Returns metadata for the specified input file
195
+ func (t * Transcoder ) GetMetadata () ( transcoder.Metadata , error ) {
155
196
156
197
if t .config .FfprobeBinPath != "" {
157
198
var outb , errb bytes.Buffer
@@ -173,6 +214,8 @@ func (t *Transcoder) getMetadata() (metadata *Metadata, err error) {
173
214
return nil , fmt .Errorf ("error executing (%s) with args (%s) | error: %s | message: %s %s" , t .config .FfprobeBinPath , args , err , outb .String (), errb .String ())
174
215
}
175
216
217
+ var metadata Metadata
218
+
176
219
if err = json .Unmarshal ([]byte (outb .String ()), & metadata ); err != nil {
177
220
return nil , err
178
221
}
@@ -256,7 +299,7 @@ func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress
256
299
}
257
300
258
301
timesec := utils .DurToSec (currentTime )
259
- dursec , _ := strconv .ParseFloat (t .metadata .Format . Duration , 64 )
302
+ dursec , _ := strconv .ParseFloat (t .metadata .GetFormat (). GetDuration () , 64 )
260
303
261
304
progress := (timesec * 100 ) / dursec
262
305
Progress .Progress = progress
0 commit comments