diff --git a/.gitignore b/.gitignore index b932f2d..5535d2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ main.go -build \ No newline at end of file +build +example diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ffc5eff --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/../../../../../../../:\Users\LA\go\src\transcoder-plus\.idea/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..065fd6a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.idea/transcoder-plus.iml b/.idea/transcoder-plus.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/transcoder-plus.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/transcoder.iml b/.idea/transcoder.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/transcoder.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..5ace414 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/README.md b/README.md index 651b613..dc5919b 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,20 @@ -# Golang Transcoding Library - -
- -
- - - Build Status - - - - - Build Status - - -
- -
- -
- Created by FlooStack. -
+# Transcoder plus ## Features
Ease use
Implement your own business logic around easy interfaces
-
Transcoding progress
Obtain progress events generated by transcoding application process
-## Download from Github +add:支持多文件输入 + +## Download from GitLab ```shell -go get github.com/floostack/transcoder +go get -u http://gitlab.yiban.io/we-work-go-team/transcoder-plus ``` ## Example @@ -45,31 +25,41 @@ package main import ( "log" - ffmpeg "github.com/floostack/transcoder/ffmpeg" + "transcoderplus/ffmpeg" ) func main() { - - format := "mp4" + + inputformat := "mulaw" + filtercomplex := "amix=inputs=2" + audiorate := 8000 + outputformat := "mp3" overwrite := true - opts := ffmpeg.Options{ - OutputFormat: &format, - Overwrite: &overwrite, + outputopts := ffmpeg.Options{ + OutputFormat: &outputformat, + Overwrite: &overwrite, + FilterComplex: &filtercomplex, + } + + inputopts := ffmpeg.Options{ + OutputFormat: &inputformat, + AudioRate: &audiorate, } ffmpegConf := &ffmpeg.Config{ - FfmpegBinPath: "/usr/local/bin/ffmpeg", - FfprobeBinPath: "/usr/local/bin/ffprobe", + FfmpegBinPath: "ffmpegPath", + FfprobeBinPath: "ffprobePath", ProgressEnabled: true, } progress, err := ffmpeg. New(ffmpegConf). - Input("/tmp/avi"). - Output("/tmp/mp4"). - WithOptions(opts). - Start(opts) + Input("inputfile1Path"). + Input("inputfile2Path"). + Output("outputfile1Path"). + WithOptions(outputopts). + Start(inputopts) if err != nil { log.Fatal(err) @@ -79,4 +69,9 @@ func main() { log.Printf("%+v", msg) } } + ``` + +## 项目源地址 + +https://github.com/floostack/transcoder diff --git a/config.go b/config.go index 527258a..3e1454f 100644 --- a/config.go +++ b/config.go @@ -1,4 +1,4 @@ -package transcoder +package transcoderplus // Config ... type Config interface{} diff --git a/ffmpeg/ffmpeg.go b/ffmpeg/ffmpeg.go index ea84fbc..dc0cef0 100644 --- a/ffmpeg/ffmpeg.go +++ b/ffmpeg/ffmpeg.go @@ -13,17 +13,17 @@ import ( "strconv" "strings" - "github.com/floostack/transcoder" - "github.com/floostack/transcoder/utils" + "transcoderplus" + "transcoderplus/utils" ) // Transcoder ... type Transcoder struct { config *Config - input string + input []string output []string options [][]string - metadata transcoder.Metadata + metadata transcoderplus.Metadata inputPipeReader *io.ReadCloser outputPipeReader *io.ReadCloser inputPipeWriter *io.WriteCloser @@ -31,16 +31,17 @@ type Transcoder struct { } // New ... -func New(cfg *Config) transcoder.Transcoder { +func New(cfg *Config) transcoderplus.Transcoder { return &Transcoder{config: cfg} } // Start ... -func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, error) { +func (t *Transcoder) Start(opts transcoderplus.Options) (<-chan transcoderplus.Progress, error) { var stderrIn io.ReadCloser + var err error - out := make(chan transcoder.Progress) + out := make(chan transcoderplus.Progress) defer t.closePipes() @@ -49,18 +50,25 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, return nil, err } - // Get file metadata - _, err := t.GetMetadata() - if err != nil { - return nil, err - } + // 不能使用,因为ffprobe不支持mulaw格式的识别 + //Get file metadata + //_, err = t.GetMetadata() + //if err != nil { + // return nil, err + //} // Append input file and standard options - args := append([]string{"-i", t.input}, opts.GetStrArguments()...) + arg := make([]string, 0) + arg = append(arg, t.input...) + args := make([]string, 0) + for _, input := range t.input { + args = append(args, opts.GetStrArguments()...) + args = append(args, []string{"-i", input}...) + } outputLength := len(t.output) optionsLength := len(t.options) - if outputLength == 1 && optionsLength == 0 { + if optionsLength == 0 { // Just append the 1 output file we've got args = append(args, t.output[0]) } else { @@ -88,7 +96,7 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, 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) + return nil, fmt.Errorf("failed getting transcoding progress (%s) with args (%s) with error %s", t.config.FfmpegBinPath, args, err) } } @@ -99,7 +107,7 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, // 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) + 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 { @@ -119,19 +127,19 @@ func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, } // Input ... -func (t *Transcoder) Input(arg string) transcoder.Transcoder { - t.input = arg +func (t *Transcoder) Input(arg string) transcoderplus.Transcoder { + t.input = append(t.input, arg) return t } // Output ... -func (t *Transcoder) Output(arg string) transcoder.Transcoder { +func (t *Transcoder) Output(arg string) transcoderplus.Transcoder { t.output = append(t.output, arg) return t } // InputPipe ... -func (t *Transcoder) InputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.Transcoder { +func (t *Transcoder) InputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoderplus.Transcoder { if &t.input == nil { t.inputPipeWriter = w t.inputPipeReader = r @@ -140,7 +148,7 @@ func (t *Transcoder) InputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.T } // OutputPipe ... -func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.Transcoder { +func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoderplus.Transcoder { if &t.output == nil { t.outputPipeWriter = w t.outputPipeReader = r @@ -149,13 +157,13 @@ func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder. } // WithOptions Sets the options object -func (t *Transcoder) WithOptions(opts transcoder.Options) transcoder.Transcoder { +func (t *Transcoder) WithOptions(opts transcoderplus.Options) transcoderplus.Transcoder { t.options = [][]string{opts.GetStrArguments()} return t } // WithAdditionalOptions Appends an additional options object -func (t *Transcoder) WithAdditionalOptions(opts transcoder.Options) transcoder.Transcoder { +func (t *Transcoder) WithAdditionalOptions(opts transcoderplus.Options) transcoderplus.Transcoder { t.options = append(t.options, opts.GetStrArguments()) return t } @@ -166,7 +174,7 @@ func (t *Transcoder) validate() error { return errors.New("ffmpeg binary path not found") } - if t.input == "" { + if t.input == nil { return errors.New("missing input option") } @@ -192,44 +200,43 @@ func (t *Transcoder) validate() error { } // GetMetadata Returns metadata for the specified input file -func (t *Transcoder) GetMetadata() ( transcoder.Metadata, error) { +func (t *Transcoder) GetMetadata() (transcoderplus.Metadata, error) { if t.config.FfprobeBinPath != "" { - var outb, errb bytes.Buffer - - input := t.input - - if t.inputPipeReader != nil { - input = "pipe:" - } + //var metadata []Metadata + var metapice Metadata - args := []string{"-i", input, "-print_format", "json", "-show_format", "-show_streams", "-show_error"} + input := t.input[0] - cmd := exec.Command(t.config.FfprobeBinPath, args...) - cmd.Stdout = &outb - cmd.Stderr = &errb + var outb, errb bytes.Buffer - err := cmd.Run() - if err != nil { - return nil, fmt.Errorf("error executing (%s) with args (%s) | error: %s | message: %s %s", t.config.FfprobeBinPath, args, err, outb.String(), errb.String()) - } + if t.inputPipeReader != nil { + input = "pipe:" + } - var metadata Metadata + args := []string{"-i", input, "-print_format", "json", "-show_format", "-show_streams", "-show_error"} - if err = json.Unmarshal([]byte(outb.String()), &metadata); err != nil { - return nil, err - } + cmd := exec.Command(t.config.FfprobeBinPath, args...) + cmd.Stdout = &outb + cmd.Stderr = &errb + err := cmd.Run() + if err != nil { + return nil, fmt.Errorf("error executing (%s) with args (%s) | error: %s | message: %s %s", t.config.FfprobeBinPath, args, err, outb.String(), errb.String()) + } + if err := json.Unmarshal([]byte(outb.String()), &metapice); err != nil { + return nil, err + } - t.metadata = metadata + t.metadata = metapice - return metadata, nil + return metapice, nil } return nil, errors.New("ffprobe binary not found") } // progress sends through given channel the transcoding status -func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress) { +func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoderplus.Progress) { defer stream.Close() @@ -298,6 +305,7 @@ func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress } } + // 都可以删,因为没有ffprobe timesec := utils.DurToSec(currentTime) dursec, _ := strconv.ParseFloat(t.metadata.GetFormat().GetDuration(), 64) @@ -318,11 +326,11 @@ func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress func (t *Transcoder) closePipes() { if t.inputPipeReader != nil { ipr := *t.inputPipeReader - ipr.Close() + _ = ipr.Close() } if t.outputPipeWriter != nil { opr := *t.outputPipeWriter - opr.Close() + _ = opr.Close() } } diff --git a/ffmpeg/metadata.go b/ffmpeg/metadata.go index 4e81910..1ddc2bd 100644 --- a/ffmpeg/metadata.go +++ b/ffmpeg/metadata.go @@ -1,6 +1,6 @@ package ffmpeg -import "github.com/floostack/transcoder" +import "transcoderplus" // Metadata ... type Metadata struct { @@ -75,12 +75,12 @@ type Disposition struct { } // GetFormat ... -func (m Metadata) GetFormat() transcoder.Format { +func (m Metadata) GetFormat() transcoderplus.Format { return m.Format } // GetStreams ... -func (m Metadata) GetStreams() (streams []transcoder.Streams) { +func (m Metadata) GetStreams() (streams []transcoderplus.Streams) { for _, element := range m.Streams { streams = append(streams, element) } @@ -133,7 +133,7 @@ func (f Format) GetProbeScore() int { } // GetTags ... -func (f Format) GetTags() transcoder.Tags { +func (f Format) GetTags() transcoderplus.Tags { return f.Tags } @@ -278,7 +278,7 @@ func (s Streams) GetDuration() string { } //GetDisposition ... -func (s Streams) GetDisposition() transcoder.Disposition { +func (s Streams) GetDisposition() transcoderplus.Disposition { return s.Disposition } diff --git a/ffmpeg/options.go b/ffmpeg/options.go index 323d4b3..b54fce9 100644 --- a/ffmpeg/options.go +++ b/ffmpeg/options.go @@ -65,6 +65,7 @@ type Options struct { PixFmt *string `flag:"-pix_fmt"` WhiteListProtocols []string `flag:"-protocol_whitelist"` Overwrite *bool `flag:"-y"` + FilterComplex *string `flag:"-filter_complex"` ExtraArgs map[string]interface{} } @@ -102,7 +103,7 @@ func (opts Options) GetStrArguments() []string { values = append(values, k, fmt.Sprintf("%v", v)) } } - + if vi, ok := value.(*int); ok { values = append(values, flag, fmt.Sprintf("%d", *vi)) } diff --git a/go.mod b/go.mod index 4c9ade4..e0ac3bc 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/floostack/transcoder +module transcoderplus go 1.13 diff --git a/metadata.go b/metadata.go index d03241d..0e5e16b 100644 --- a/metadata.go +++ b/metadata.go @@ -1,4 +1,4 @@ -package transcoder +package transcoderplus // Metadata ... type Metadata interface { diff --git a/options.go b/options.go index 3813a9f..4904f4d 100644 --- a/options.go +++ b/options.go @@ -1,4 +1,4 @@ -package transcoder +package transcoderplus // Options ... type Options interface { diff --git a/progress.go b/progress.go index 4b7b060..7b8eeba 100644 --- a/progress.go +++ b/progress.go @@ -1,4 +1,4 @@ -package transcoder +package transcoderplus // Progress ... type Progress interface { diff --git a/transcoder.go b/transcoder.go index 9e58206..ac63938 100644 --- a/transcoder.go +++ b/transcoder.go @@ -1,4 +1,4 @@ -package transcoder +package transcoderplus import ( "io"