add example; add escape

move sample data
This commit is contained in:
wanglei.w
2020-11-11 22:38:49 +08:00
parent b260b92d8a
commit 5a1890c3e8
18 changed files with 134 additions and 65 deletions

23
examples/example_test.go Normal file
View File

@@ -0,0 +1,23 @@
package examples
import (
"testing"
"github.com/disintegration/imaging"
)
func TestExampleStream(t *testing.T) {
ExampleStream("./sample_data/in1.mp4", "./sample_data/out1.mp4", false)
}
func TestExampleReadFramAsJpeg(t *testing.T) {
reader := ExampleReadFrameAsJpeg("./sample_data/in1.mp4", 5)
img, err := imaging.Decode(reader)
if err != nil {
t.Fatal(err)
}
err = imaging.Save(img, "./sample_data/out1.jpeg")
if err != nil {
t.Fatal(err)
}
}

View File

@@ -4,4 +4,7 @@ go 1.14
replace github.com/u2takey/ffmpeg-go => ../../ffmpeg-go replace github.com/u2takey/ffmpeg-go => ../../ffmpeg-go
require github.com/u2takey/ffmpeg-go v0.0.0-00010101000000-000000000000 require (
github.com/disintegration/imaging v1.6.2
github.com/u2takey/ffmpeg-go v0.0.0-00010101000000-000000000000
)

View File

@@ -1,6 +1,8 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
@@ -30,6 +32,8 @@ github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 h1:PT7mE8HJE1mwaSazrOdSeByJ1FoV33/fHUZrBB+zwVU= github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 h1:PT7mE8HJE1mwaSazrOdSeByJ1FoV33/fHUZrBB+zwVU=
github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7/go.mod h1:ATqKFpgjUIlhGRs8j59gXmu8Cmpo1QQEHV6vwu1hs28= github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7/go.mod h1:ATqKFpgjUIlhGRs8j59gXmu8Cmpo1QQEHV6vwu1hs28=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

View File

@@ -0,0 +1,23 @@
package examples
import (
"bytes"
"fmt"
"io"
"os"
ffmpeg "github.com/u2takey/ffmpeg-go"
)
func ExampleReadFrameAsJpeg(inFileName string, frameNum int) io.Reader {
buf := bytes.NewBuffer(nil)
err := ffmpeg.Input(inFileName).
Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}).
Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}).
WithOutput(buf, os.Stdout).
Run()
if err != nil {
panic(err)
}
return buf
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,41 +1,14 @@
package main package examples
import ( import (
"bytes"
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"io" "io"
"log" "log"
"sync"
ffmpeg "github.com/u2takey/ffmpeg-go" ffmpeg "github.com/u2takey/ffmpeg-go"
) )
var (
InputFile = flag.String("in_filename", "./in1.mp4", "Input filename")
OutputFile = flag.String("out_filename", "./out.mp4", "Input filename")
Dream = flag.Bool("dream", false, "Use DeepDream frame processing (requires tensorflow)")
)
// Buffer is a goroutine safe bytes.Buffer
type Buffer struct {
buffer bytes.Buffer
mutex sync.Mutex
}
func (s *Buffer) Write(p []byte) (n int, err error) {
s.mutex.Lock()
defer s.mutex.Unlock()
return s.buffer.Write(p)
}
func (s *Buffer) Read(p []byte) (n int, err error) {
s.mutex.Lock()
defer s.mutex.Unlock()
return s.buffer.Read(p)
}
func getVideoSize(fileName string) (int, int) { func getVideoSize(fileName string) (int, int) {
log.Println("Getting video size for", fileName) log.Println("Getting video size for", fileName)
data, err := ffmpeg.Probe(fileName) data, err := ffmpeg.Probe(fileName)
@@ -125,7 +98,7 @@ func process(reader io.ReadCloser, writer io.WriteCloser, w, h int) {
return return
} }
func run(inFile, outFile string) { func runExampleStream(inFile, outFile string) {
w, h := getVideoSize(inFile) w, h := getVideoSize(inFile)
log.Println(w, h) log.Println(w, h)
@@ -145,11 +118,20 @@ func run(inFile, outFile string) {
log.Println("Done") log.Println("Done")
} }
func main() { // ExampleStream
flag.Parse() // inFileName: input filename
if *Dream == true { // outFileName: output filename
fmt.Println("tensorflow mode not implemented, todo") // dream: Use DeepDream frame processing (requires tensorflow)
return func ExampleStream(inFileName, outFileName string, dream bool) {
if inFileName == "" {
inFileName = "./in1.mp4"
} }
run(*InputFile, *OutputFile) if outFileName == "" {
outFileName = "./out.mp4"
}
if dream {
panic("Use DeepDream With Tensorflow haven't been implemented")
}
runExampleStream(inFileName, outFileName)
} }

View File

@@ -9,6 +9,12 @@ import (
"github.com/u2takey/go-utils/rand" "github.com/u2takey/go-utils/rand"
) )
const (
TestInputFile1 = "./examples/sample_data/in1.mp4"
TestOutputFile1 = "./examples/sample_data/out1.mp4"
TestOverlayFile = "./examples/sample_data/overlay.png"
)
func TestFluentEquality(t *testing.T) { func TestFluentEquality(t *testing.T) {
base1 := Input("dummy1.mp4") base1 := Input("dummy1.mp4")
base2 := Input("dummy1.mp4") base2 := Input("dummy1.mp4")
@@ -120,7 +126,7 @@ func TestFilterWithSelector(t *testing.T) {
i := Input(TestInputFile1) i := Input(TestInputFile1)
v1 := i.Video().HFlip() v1 := i.Video().HFlip()
a1 := i.Audio().Filter("aecho", []string{"0.8", "0.9", "1000", "0.3"}) a1 := i.Audio().Filter("aecho", Args{"0.8", "0.9", "1000", "0.3"})
out := Output([]*Stream{a1, v1}, TestOutputFile1) out := Output([]*Stream{a1, v1}, TestOutputFile1)
assert.Equal(t, []string{ assert.Equal(t, []string{

View File

@@ -11,15 +11,15 @@ func AssetType(hasType, expectType string, action string) {
} }
} }
func FilterMultiOutput(streamSpec []*Stream, filterName string, args []string, kwArgs ...KwArgs) *Node { func FilterMultiOutput(streamSpec []*Stream, filterName string, args Args, kwArgs ...KwArgs) *Node {
return NewFilterNode(filterName, streamSpec, -1, args, MergeKwArgs(kwArgs)) return NewFilterNode(filterName, streamSpec, -1, args, MergeKwArgs(kwArgs))
} }
func Filter(streamSpec []*Stream, filterName string, args []string, kwArgs ...KwArgs) *Stream { func Filter(streamSpec []*Stream, filterName string, args Args, kwArgs ...KwArgs) *Stream {
return FilterMultiOutput(streamSpec, filterName, args, MergeKwArgs(kwArgs)).Stream("", "") return FilterMultiOutput(streamSpec, filterName, args, MergeKwArgs(kwArgs)).Stream("", "")
} }
func (s *Stream) Filter(filterName string, args []string, kwArgs ...KwArgs) *Stream { func (s *Stream) Filter(filterName string, args Args, kwArgs ...KwArgs) *Stream {
AssetType(s.Type, "FilterableStream", "filter") AssetType(s.Type, "FilterableStream", "filter")
return Filter([]*Stream{s}, filterName, args, MergeKwArgs(kwArgs)) return Filter([]*Stream{s}, filterName, args, MergeKwArgs(kwArgs))
} }

1
go.mod
View File

@@ -3,6 +3,7 @@ module github.com/u2takey/ffmpeg-go
go 1.14 go 1.14
require ( require (
github.com/disintegration/imaging v1.6.2 // indirect
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/tidwall/gjson v1.6.3 github.com/tidwall/gjson v1.6.3
github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7

4
go.sum
View File

@@ -1,6 +1,8 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
@@ -30,6 +32,8 @@ github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 h1:PT7mE8HJE1mwaSazrOdSeByJ1FoV33/fHUZrBB+zwVU= github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 h1:PT7mE8HJE1mwaSazrOdSeByJ1FoV33/fHUZrBB+zwVU=
github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7/go.mod h1:ATqKFpgjUIlhGRs8j59gXmu8Cmpo1QQEHV6vwu1hs28= github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7/go.mod h1:ATqKFpgjUIlhGRs8j59gXmu8Cmpo1QQEHV6vwu1hs28=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

12
node.go
View File

@@ -248,13 +248,12 @@ func (n *Node) GetFilter(outgoingEdges []DagEdge) string {
if n.nodeType != "FilterNode" { if n.nodeType != "FilterNode" {
panic("call GetFilter on non-FilterNode") panic("call GetFilter on non-FilterNode")
} }
args := n.args args, kwargs, ret := n.args, n.kwargs, ""
kwargs := n.kwargs
if n.name == "split" || n.name == "asplit" { if n.name == "split" || n.name == "asplit" {
args = []string{fmt.Sprintf("%d", len(outgoingEdges))} args = []string{fmt.Sprintf("%d", len(outgoingEdges))}
} }
// todo escape char args = Args(args).EscapeWith("\\'=:")
for _, k := range kwargs.SortedKeys() { for _, k := range kwargs.EscapeWith("\\'=:").SortedKeys() {
v := getString(kwargs[k]) v := getString(kwargs[k])
if v != "" { if v != "" {
args = append(args, fmt.Sprintf("%s=%s", k, v)) args = append(args, fmt.Sprintf("%s=%s", k, v))
@@ -262,8 +261,9 @@ func (n *Node) GetFilter(outgoingEdges []DagEdge) string {
args = append(args, fmt.Sprintf("%s", k)) args = append(args, fmt.Sprintf("%s", k))
} }
} }
ret = escapeChars(n.name, "\\'=:")
if len(args) > 0 { if len(args) > 0 {
return fmt.Sprintf("%s=%s", n.name, strings.Join(args, ":")) ret += fmt.Sprintf("=%s", strings.Join(args, ":"))
} }
return fmt.Sprintf("%s", n.name) return escapeChars(ret, "\\'[],;")
} }

View File

@@ -7,12 +7,6 @@ import (
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
) )
const (
TestInputFile1 = "./sample_data/in1.mp4"
TestOutputFile1 = "./sample_data/out1.mp4"
TestOverlayFile = "./sample_data/overlay.png"
)
func TestProbe(t *testing.T) { func TestProbe(t *testing.T) {
data, err := Probe(TestInputFile1, nil) data, err := Probe(TestInputFile1, nil)
assert.Nil(t, err) assert.Nil(t, err)

2
run.go
View File

@@ -57,8 +57,6 @@ func _getFilterSpec(node *Node, outOutingEdgeMap map[Label][]NodeInfo, streamNam
for _, e := range outEdges { for _, e := range outEdges {
output = append(output, formatOutStreamName(streamNameMap, e)) output = append(output, formatOutStreamName(streamNameMap, e))
} }
//sort.Strings(input)
//sort.Strings(output)
return fmt.Sprintf("%s%s%s", strings.Join(input, ""), node.GetFilter(outEdges), strings.Join(output, "")) return fmt.Sprintf("%s%s%s", strings.Join(input, ""), node.GetFilter(outEdges), strings.Join(output, ""))
} }

Binary file not shown.

View File

@@ -6,6 +6,8 @@ import (
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"github.com/u2takey/go-utils/sets"
) )
func getString(item interface{}) string { func getString(item interface{}) string {
@@ -17,6 +19,8 @@ func getString(item interface{}) string {
return a return a
case []string: case []string:
return strings.Join(a, ", ") return strings.Join(a, ", ")
case Args:
return strings.Join(a, ", ")
case []interface{}: case []interface{}:
var r []string var r []string
for _, b := range a { for _, b := range a {
@@ -76,17 +80,36 @@ func getHash(item interface{}) int {
} }
} }
//def escape_chars(text, chars): func escapeChars(text, chars string) string {
// """Helper function to escape uncomfortable characters.""" s := sets.NewString()
// text = str(text) for _, a := range chars {
// chars = list(set(chars)) s.Insert(string(a))
// if '\\' in chars: }
// chars.remove('\\') sl := s.List()
// chars.insert(0, '\\') if s.Has("\\") {
// for ch in chars: s.Delete("\\")
// text = text.replace(ch, '\\' + ch) sl = append([]string{"\\"}, s.List()...)
// return text }
// for _, ch := range sl {
text = strings.ReplaceAll(text, ch, "\\"+ch)
}
return text
}
type Args []string
func (a Args) Sorted() Args {
sort.Strings(a)
return a
}
func (a Args) EscapeWith(chars string) Args {
out := Args{}
for _, b := range a {
out = append(out, escapeChars(b, chars))
}
return out
}
type KwArgs map[string]interface{} type KwArgs map[string]interface{}
@@ -100,6 +123,14 @@ func MergeKwArgs(args []KwArgs) KwArgs {
return a return a
} }
func (a KwArgs) EscapeWith(chars string) KwArgs {
out := KwArgs{}
for k, v := range a {
out[escapeChars(k, chars)] = escapeChars(getString(v), chars)
}
return out
}
func (a KwArgs) Copy() KwArgs { func (a KwArgs) Copy() KwArgs {
r := KwArgs{} r := KwArgs{}
for k := range a { for k := range a {