diff --git a/README.md b/README.md index 651b613..570791b 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,6 @@ # Golang Transcoding Library -
- -
- - - Build Status - - - - - Build Status - - -
- -
- -
- Created by FlooStack. -
+> This repository is no longer maintained. Please use [Goffmpeg](https://github.com/xfrr/goffmpeg). ## Features @@ -50,10 +31,19 @@ import ( func main() { + + hwaccel := "cuvid" + videoCodec := "h264_cuvid" + + inputOpts := ffmpeg.Options{ + Hwaccel: &hwaccel, + VideoCodec: &videoCodec, + } + format := "mp4" overwrite := true - opts := ffmpeg.Options{ + outputOpts := ffmpeg.Options{ OutputFormat: &format, Overwrite: &overwrite, } @@ -68,8 +58,9 @@ func main() { New(ffmpegConf). Input("/tmp/avi"). Output("/tmp/mp4"). - WithOptions(opts). - Start(opts) + WithInputOptions(inputOpts). + WithOutputOptions(outputOpts). + Start() if err != nil { log.Fatal(err) diff --git a/ffmpeg/ffmpeg.go b/ffmpeg/ffmpeg.go index ea84fbc..6328104 100644 --- a/ffmpeg/ffmpeg.go +++ b/ffmpeg/ffmpeg.go @@ -3,6 +3,7 @@ package ffmpeg import ( "bufio" "bytes" + "context" "encoding/json" "errors" "fmt" @@ -22,12 +23,14 @@ type Transcoder struct { config *Config input string output []string - options [][]string + inputOptions []string + outputOptions [][]string metadata transcoder.Metadata inputPipeReader *io.ReadCloser outputPipeReader *io.ReadCloser inputPipeWriter *io.WriteCloser outputPipeWriter *io.WriteCloser + commandContext *context.Context } // New ... @@ -36,7 +39,7 @@ func New(cfg *Config) transcoder.Transcoder { } // Start ... -func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, error) { +func (t *Transcoder) Start() (<-chan transcoder.Progress, error) { var stderrIn io.ReadCloser @@ -56,24 +59,30 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, } // Append input file and standard options - args := append([]string{"-i", t.input}, opts.GetStrArguments()...) + var args []string + + if len(t.inputOptions) > 0 { + args = append(args, t.inputOptions...) + } + + args = append(args, []string{"-i", t.input}...) outputLength := len(t.output) - optionsLength := len(t.options) + outputOptionsLength := len(t.outputOptions) - if outputLength == 1 && optionsLength == 0 { + if outputLength == 1 && outputOptionsLength == 0 { // Just append the 1 output file we've got args = append(args, t.output[0]) } else { for index, out := range t.output { // Get executable flags // If we are at the last output file but still have several options, append them all at once - if index == outputLength-1 && outputLength < optionsLength { - for i := index; i < len(t.options); i++ { - args = append(args, t.options[i]...) + if index == outputLength-1 && outputLength < outputOptionsLength { + for i := index; i < len(t.outputOptions); i++ { + args = append(args, t.outputOptions[i]...) } // Otherwise just append the current options } else { - args = append(args, t.options[index]...) + args = append(args, t.outputOptions[index]...) } // Append output flag @@ -82,7 +91,15 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, } // Initialize command - cmd := exec.Command(t.config.FfmpegBinPath, args...) + // 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...) + } // If progresss enabled, get stderr pipe and start progress process if t.config.ProgressEnabled && !t.config.Verbose { @@ -148,15 +165,35 @@ func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder. return t } -// WithOptions Sets the options object -func (t *Transcoder) WithOptions(opts transcoder.Options) transcoder.Transcoder { - t.options = [][]string{opts.GetStrArguments()} +// WithInputOptions Sets the options object +func (t *Transcoder) WithInputOptions(opts transcoder.Options) transcoder.Transcoder { + t.inputOptions = opts.GetStrArguments() + return t +} + +// WithAdditionalInputOptions Appends an additional options object +func (t *Transcoder) WithAdditionalInputOptions(opts transcoder.Options) transcoder.Transcoder { + t.inputOptions = append(t.inputOptions, opts.GetStrArguments()...) + return t +} + +// WithOutputOptions Sets the options object +func (t *Transcoder) WithOutputOptions(opts transcoder.Options) transcoder.Transcoder { + t.outputOptions = [][]string{opts.GetStrArguments()} + return t +} + +// WithAdditionalOutputOptions Appends an additional options object +func (t *Transcoder) WithAdditionalOutputOptions(opts transcoder.Options) transcoder.Transcoder { + t.outputOptions = append(t.outputOptions, opts.GetStrArguments()) return t } -// WithAdditionalOptions Appends an additional options object -func (t *Transcoder) WithAdditionalOptions(opts transcoder.Options) transcoder.Transcoder { - t.options = append(t.options, opts.GetStrArguments()) +// WithContext is to be used on a Transcoder *before Starting* to +// pass in a context.Context object that can be used to kill +// a running transcoder process. Usage of this method is optional +func (t *Transcoder) WithContext(ctx *context.Context) transcoder.Transcoder { + t.commandContext = ctx return t } @@ -178,7 +215,7 @@ func (t *Transcoder) validate() error { // length of output files being greater than length of options would produce an invalid ffmpeg command // unless there is only 1 output file, which obviously wouldn't be a problem - if outputLength > len(t.options) && outputLength != 1 { + if outputLength > len(t.outputOptions) && outputLength != 1 { return errors.New("number of options and output files does not match") } @@ -192,7 +229,7 @@ func (t *Transcoder) validate() error { } // GetMetadata Returns metadata for the specified input file -func (t *Transcoder) GetMetadata() ( transcoder.Metadata, error) { +func (t *Transcoder) GetMetadata() (transcoder.Metadata, error) { if t.config.FfprobeBinPath != "" { var outb, errb bytes.Buffer @@ -262,7 +299,7 @@ func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress Progress := new(Progress) line := scanner.Text() - if strings.Contains(line, "frame=") && strings.Contains(line, "time=") && strings.Contains(line, "bitrate=") { + if strings.Contains(line, "time=") && strings.Contains(line, "bitrate=") { var re = regexp.MustCompile(`=\s+`) st := re.ReplaceAllString(line, `=`) diff --git a/ffmpeg/options.go b/ffmpeg/options.go index 43918bb..323d4b3 100644 --- a/ffmpeg/options.go +++ b/ffmpeg/options.go @@ -97,9 +97,9 @@ func (opts Options) GetStrArguments() []string { } } - if vm, ok := value.(map[string]string); ok { + if vm, ok := value.(map[string]interface{}); ok { for k, v := range vm { - values = append(values, flag, fmt.Sprintf("%v:%v", k, v)) + values = append(values, k, fmt.Sprintf("%v", v)) } } @@ -111,4 +111,4 @@ func (opts Options) GetStrArguments() []string { } return values -} \ No newline at end of file +} diff --git a/transcoder.go b/transcoder.go index 9e58206..f53ca4e 100644 --- a/transcoder.go +++ b/transcoder.go @@ -1,17 +1,21 @@ package transcoder import ( + "context" "io" ) // Transcoder ... type Transcoder interface { - Start(opts Options) (<-chan Progress, error) + Start() (<-chan Progress, error) Input(i string) Transcoder InputPipe(w *io.WriteCloser, r *io.ReadCloser) Transcoder Output(o string) Transcoder OutputPipe(w *io.WriteCloser, r *io.ReadCloser) Transcoder - WithOptions(opts Options) Transcoder - WithAdditionalOptions(opts Options) Transcoder + WithInputOptions(opts Options) Transcoder + WithAdditionalInputOptions(opts Options) Transcoder + WithOutputOptions(opts Options) Transcoder + WithAdditionalOutputOptions(opts Options) Transcoder + WithContext(ctx *context.Context) Transcoder GetMetadata() (Metadata, error) } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy