diff --git a/ffmpeg/config.go b/ffmpeg/config.go index 05eb7ff..618dc8b 100644 --- a/ffmpeg/config.go +++ b/ffmpeg/config.go @@ -6,4 +6,5 @@ type Config struct { FfprobeBinPath string ProgressEnabled bool Verbose bool + OutputDir string } diff --git a/ffmpeg/ffmpeg.go b/ffmpeg/ffmpeg.go index ce262f8..bd8d005 100644 --- a/ffmpeg/ffmpeg.go +++ b/ffmpeg/ffmpeg.go @@ -30,11 +30,68 @@ type Transcoder struct { inputPipeWriter *io.WriteCloser outputPipeWriter *io.WriteCloser commandContext *context.Context + done chan interface{} } // New ... func New(cfg *Config) transcoder.Transcoder { - return &Transcoder{config: cfg} + return &Transcoder{config: cfg, done: make(chan interface{})} +} + +func (t *Transcoder) StartCustom(opts transcoder.Options) (<-chan transcoder.Progress, error) { + var stderrIn io.ReadCloser + + out := make(chan transcoder.Progress) + + defer t.closePipes() + + // Append input file and standard options + args := append([]string{}, opts.GetStrArguments()...) + + // Initialize command + // If a context object was supplied to this Transcoder before + // starting, use this context when creating the command to allow + // the command to be killed when the context expires + var cmd *exec.Cmd + if t.commandContext == nil { + cmd = exec.Command(t.config.FfmpegBinPath, args...) + } else { + cmd = exec.CommandContext(*t.commandContext, t.config.FfmpegBinPath, args...) + } + cmd.Dir = t.config.OutputDir + var err error + // If progresss enabled, get stderr pipe and start progress process + if t.config.ProgressEnabled && !t.config.Verbose { + stderrIn, err = cmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("Failed getting transcoding progress (%s) with args (%s) with error %s", t.config.FfmpegBinPath, args, err) + } + } + + if t.config.Verbose { + cmd.Stderr = os.Stdout + } + + // Start process + err = cmd.Start() + if err != nil { + return nil, fmt.Errorf("Failed starting transcoding (%s) with args (%s) with error %s", t.config.FfmpegBinPath, args, err) + } + if t.config.ProgressEnabled && !t.config.Verbose { + go func() { + t.progress(stderrIn, out) + }() + + go func() { + err = cmd.Wait() + t.done <- true + close(out) + }() + } else { + err = cmd.Wait() + } + + return out, nil } // Start ... @@ -54,7 +111,7 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, // Get file metadata _, err := t.GetMetadata() if err != nil { - return nil, err + //return nil, err } // Append input file and standard options @@ -93,6 +150,7 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, } else { cmd = exec.CommandContext(*t.commandContext, t.config.FfmpegBinPath, args...) } + cmd.Dir = t.config.OutputDir // If progresss enabled, get stderr pipe and start progress process if t.config.ProgressEnabled && !t.config.Verbose { @@ -118,8 +176,9 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, }() go func() { - defer close(out) err = cmd.Wait() + t.done <- true + close(out) }() } else { err = cmd.Wait() @@ -221,7 +280,7 @@ func (t *Transcoder) GetMetadata() (transcoder.Metadata, error) { input = "pipe:" } - args := []string{"-i", input, "-print_format", "json", "-show_format", "-show_streams", "-show_error"} + args := []string{"-print_format", "json", "-show_format", "-show_streams", "-find_stream_info", "-analyzeduration", "10000000", "-probesize", "10000000", "-show_error", input} cmd := exec.Command(t.config.FfprobeBinPath, args...) cmd.Stdout = &outb @@ -243,7 +302,7 @@ func (t *Transcoder) GetMetadata() (transcoder.Metadata, error) { return metadata, nil } - return nil, errors.New("ffprobe binary not found") + return nil, nil // errors.New("ffprobe binary not found") } // progress sends through given channel the transcoding status @@ -327,9 +386,17 @@ func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress Progress.CurrentTime = currentTime Progress.Speed = currentSpeed + select { + case <-t.done: + return + default: + } + out <- *Progress } } + + close(out) } // closePipes Closes pipes if opened diff --git a/transcoder.go b/transcoder.go index c93bc4a..1c5b4ea 100644 --- a/transcoder.go +++ b/transcoder.go @@ -8,6 +8,7 @@ import ( // Transcoder ... type Transcoder interface { Start(opts Options) (<-chan Progress, error) + StartCustom(opts Options) (<-chan Progress, error) Input(i string) Transcoder InputPipe(w *io.WriteCloser, r *io.ReadCloser) Transcoder Output(o string) Transcoder