summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorb5f0d6c3 <[email protected]>2022-05-06 10:46:55 +0800
committerb5f0d6c3 <[email protected]>2022-05-06 10:46:55 +0800
commit79f40d4f7bedf2554d072f6ded4eb73373dd7319 (patch)
treebef73cc28e3800ec02d3764302eddbc601ff8d8c
parent8c382de8c87260d68b9c10e2bf687cbd53e3beb8 (diff)
update
-rw-r--r--mkvlib/c/exports.go26
-rw-r--r--mkvlib/mkv.go128
-rw-r--r--mkvlib/shared.go13
-rw-r--r--mkvtool/main.go15
-rw-r--r--mkvtool/utils.go28
5 files changed, 134 insertions, 76 deletions
diff --git a/mkvlib/c/exports.go b/mkvlib/c/exports.go
index 1c12825..fc5965d 100644
--- a/mkvlib/c/exports.go
+++ b/mkvlib/c/exports.go
@@ -215,6 +215,32 @@ func GetFontInfo(p *C.char) *C.char {
return cs(string(data))
}
+//export Version
+func Version() *C.char {
+ return cs(mkvlib.Version())
+}
+
+//export CreateBlankOrBurnVideo
+func CreateBlankOrBurnVideo(t int64, s, enc, ass, fontdir, output *C.char) bool {
+ if !checkInstance() {
+ return false
+ }
+ return getter.GetProcessorInstance().CreateBlankOrBurnVideo(t, gs(s), gs(enc), gs(ass), gs(fontdir), gs(output))
+}
+
+//export CreateTestVideo
+func CreateTestVideo(asses, s, fontdir, enc *C.char, burn bool, lcb C.logCallback) bool {
+ if !checkInstance() {
+ return false
+ }
+ obj := make([]string, 0)
+ if json.Unmarshal([]byte(gs(asses)), &obj) == nil {
+ _asses := obj
+ return getter.GetProcessorInstance().CreateTestVideo(_asses, gs(s), gs(fontdir), gs(enc), burn, _lcb(lcb))
+ }
+ return false
+}
+
func cs(gs string) *C.char {
return C.CString(gs)
}
diff --git a/mkvlib/mkv.go b/mkvlib/mkv.go
index 73a16fd..bd4ed00 100644
--- a/mkvlib/mkv.go
+++ b/mkvlib/mkv.go
@@ -15,6 +15,7 @@ const (
mkvmerge = `mkvmerge`
mkvextract = `mkvextract`
ass2bdnxml = `ass2bdnxml`
+ ffmpeg = `ffmpeg`
)
type mkvInfo struct {
@@ -43,6 +44,7 @@ type mkvProcessor struct {
pf string
caches []string
ass2bdnxml bool
+ ffmpeg bool
nrename bool
check bool
strict bool
@@ -396,57 +398,101 @@ func (self *mkvProcessor) NRename(nrename bool) {
self.nrename = nrename
}
-func (self *mkvProcessor) CreateTestVideo(asses []string, fonts, enc, output string, lcb logCallback) bool {
- _obj := new(assProcessor)
+func (self *mkvProcessor) CreateBlankOrBurnVideo(t int64, s, enc, ass, fontdir, output string) bool {
+ if !self.ffmpeg {
+ return false
+ }
args := make([]string, 0)
- args = append(args, "-hide_banner", "-loglevel", "quiet")
- args = append(args, "-y", "-f", "lavfi")
- args = append(args, "-i", fmt.Sprintf("color=c=0x000000:s=%s:r=%s", self.pr, self.pf))
- var t time.Duration
- _s := len(asses) == 1
- if _s {
- t = _obj.getLength(asses[0])
- fonts = strings.ReplaceAll(fonts, `\`, `/`)
- fonts = strings.ReplaceAll(fonts, `:`, `\\:`)
- asses[0] = strings.ReplaceAll(asses[0], `\`, `/`)
- asses[0] = strings.ReplaceAll(asses[0], `:`, `\\:`)
- args = append(args, "-vf", fmt.Sprintf("subtitles=%s:fontsdir=%s", asses[0], fonts))
+ args = append(args, "-y", "-hide_banner", "-loglevel", "quiet")
+ if enc == "" {
+ enc = "libx264"
+ }
+ if s == "" {
+ args = append(args, "-f", "lavfi")
+ args = append(args, "-i", fmt.Sprintf("color=c=0x000000:s=%s:r=%s", self.pr, self.pf))
} else {
- for _, v := range asses {
- length := _obj.getLength(v)
- if length > t {
- t = length
- }
+ args = append(args, "-i", s)
+ }
+ if ass != "" && fontdir != "" {
+ t = new(assProcessor).getLength(ass).Milliseconds()
+ fontdir = strings.ReplaceAll(fontdir, `\`, `/`)
+ fontdir = strings.ReplaceAll(fontdir, `:`, `\\:`)
+ ass = strings.ReplaceAll(ass, `\`, `/`)
+ ass = strings.ReplaceAll(ass, `:`, `\\:`)
+ args = append(args, "-vf", fmt.Sprintf("subtitles=%s:fontsdir=%s", ass, fontdir))
+ }
+ if s == "" {
+ if t > 0 {
+ args = append(args, "-t", fmt.Sprintf("%dms", t))
+ } else {
+ return false
}
}
- if t == 0 {
+ args = append(args, "-pix_fmt", "nv12", "-crf", "18")
+ args = append(args, "-vcodec", enc)
+ args = append(args, output)
+ if p, err := newProcess(nil, nil, nil, "", ffmpeg, args...); err == nil {
+ s, err := p.Wait()
+ return err == nil && s.ExitCode() == 0
+ }
+ return false
+}
+
+func (self *mkvProcessor) CreateTestVideo(asses []string, s, fontdir, enc string, burn bool, lcb logCallback) bool {
+ if s == "-" {
+ s = ""
+ }
+ l := len(asses)
+ if l == 0 {
return false
}
- args = append(args, "-t", fmt.Sprintf("%dms", t.Milliseconds()))
- args = append(args, "-c:v", enc)
- args = append(args, "-c:s", "copy")
- d, _, _, ne := splitPath(output)
- _output := path.Join(d, fmt.Sprintf("%s.mp4", ne))
- args = append(args, _output)
- if p, err := newProcess(nil, os.Stdout, os.Stderr, "", "ffmpeg", args...); err == nil {
- s, err := p.Wait()
- ok := err == nil && s.ExitCode() == 0
- if ok && !_s {
- _fonts := findFonts(fonts)
- if len(_fonts) > 0 {
- __output := path.Join(d, fmt.Sprintf("%s.mkv", ne))
- ok = self.CreateMKV(_output, asses, _fonts, __output, "", "", false)
- } else {
+ if burn {
+ ec := 0
+ for i, v := range asses {
+ d, _, _, ne := splitPath(v)
+ _output := path.Join(d, fmt.Sprintf("%s-test.mp4", ne))
+ ok := self.CreateBlankOrBurnVideo(0, s, enc, v, fontdir, _output)
+ if !ok {
+ ec++
+ printLog(lcb, `Failed to create the test video file: "%s"`, _output)
+ }
+ printLog(lcb, "CT (%d/%d) done.", i+1, l)
+ }
+ return ec == 0
+ }
+ _obj := new(assProcessor)
+ var t time.Duration
+ for _, v := range asses {
+ _t := _obj.getLength(v)
+ if _t > t {
+ t = _t
+ }
+ }
+ ok := true
+ _fonts := findFonts(fontdir)
+ if len(_fonts) > 0 {
+ d, _, _, _ := splitPath(asses[0])
+ n := randomStr(8)
+ _t := s == ""
+ if _t {
+ s = path.Join(d, fmt.Sprintf("%s.mp4", n))
+ if !self.CreateBlankOrBurnVideo(t.Milliseconds(), "", enc, "", "", s) {
ok = false
+ printLog(lcb, `Failed to create the temp video file: "%s".`, s)
}
}
- if !ok || !_s {
- _ = os.Remove(_output)
+ if ok {
+ output := path.Join(d, fmt.Sprintf("%s.mkv", n))
+ if !self.CreateMKV(s, asses, _fonts, output, "", "", true) {
+ ok = false
+ printLog(lcb, `Failed to create the test video file: "%s".`, output)
+ }
}
- if !ok {
- printLog(lcb, "Failed to create the test video file.")
+ if _t {
+ _ = os.Remove(s)
}
- return ok
+ } else {
+ ok = false
}
- return false
+ return ok
}
diff --git a/mkvlib/shared.go b/mkvlib/shared.go
index 326577a..727a774 100644
--- a/mkvlib/shared.go
+++ b/mkvlib/shared.go
@@ -11,7 +11,7 @@ import (
)
const libName = "mkvlib"
-const libVer = "v1.8.6"
+const libVer = "v1.8.7"
const LibFName = libName + " " + libVer
@@ -52,6 +52,7 @@ func (self *processorGetter) InitProcessorInstance(lcb logCallback) bool {
_, _mkvextract := exec.LookPath(mkvextract)
_, _mkvmerge := exec.LookPath(mkvmerge)
_, _ass2bdnxml := exec.LookPath(ass2bdnxml)
+ _, _ffmpeg := exec.LookPath(ffmpeg)
if _ttx != nil || _pyftsubset != nil {
printLog(lcb, `Missing dependency: fonttools (need "%s" & "%s").`, ttx, pyftsubset)
ec++
@@ -66,11 +67,17 @@ func (self *processorGetter) InitProcessorInstance(lcb logCallback) bool {
//ec++
}
+ if _ffmpeg != nil {
+ printLog(lcb, `Missing dependency: ffmpeg.`)
+ //ec++
+ }
+
r := ec == 0
if r {
self.checked = true
self.instance = new(mkvProcessor)
self.instance.ass2bdnxml = _ass2bdnxml == nil
+ self.instance.ffmpeg = _ffmpeg == nil
}
return r
@@ -91,6 +98,10 @@ func printLog(lcb logCallback, f string, v ...interface{}) {
}
}
+func Version() string {
+ return libVer
+}
+
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
}
diff --git a/mkvtool/main.go b/mkvtool/main.go
index 5ce6de8..2e2501a 100644
--- a/mkvtool/main.go
+++ b/mkvtool/main.go
@@ -17,7 +17,7 @@ import (
)
const appName = "MKV Tool"
-const appVer = "v3.8.4"
+const appVer = "v3.8.5"
const tTitle = appName + " " + appVer
var appFN = fmt.Sprintf("%s %s %s/%s", appName, appVer, runtime.GOOS, runtime.GOARCH)
@@ -64,7 +64,9 @@ func main() {
mks := false
ck := false
cks := false
- t := false
+ b := false
+ t := ""
+ e := ""
sl, st := "", ""
af, ao := "", ""
flog := ""
@@ -103,6 +105,9 @@ func main() {
flag.StringVar(&flog, "log", "", "Log file path.")
flag.StringVar(&pf, "pf", "23.976", "PGS frame rate:23.976, 24, 25, 30, 29.97, 50, 59.94, 60 or custom fps like 15/1. (ass2pgs only)")
flag.StringVar(&pr, "pr", "1920*1080", "PGS resolution:720p, 1080p, 2k, or with custom resolution like 720*480. (ass2pgs only)")
+ flag.StringVar(&t, "t", "", `Create test video source path(enter "-" for blank video).`)
+ flag.BoolVar(&b, "b", false, `Create test video with burn subtitle.`)
+ flag.StringVar(&e, "e", "libx264", `Create test video use encoder.`)
flag.BoolVar(&v, "v", false, "Show app info.")
flag.Parse()
@@ -190,16 +195,14 @@ func main() {
if len(*asses) > 0 {
if !processer.ASSFontSubset(*asses, af, ao, !ans, nil) {
ec++
- } else if t {
+ } else if t != "" {
d, _, _, _ := splitPath((*asses)[0])
if ao == "" {
ao = path.Join(d, "subsetted")
}
_asses, _ := findPath(ao, `\.ass$`)
if len(_asses) > 0 {
- p := fmt.Sprintf("test-%s.a", randomStr(8))
- p = path.Join(d, p)
- processer.CreateTestVideo(_asses, ao, "nvenc_h264", p, nil)
+ processer.CreateTestVideo(_asses, t, ao, e, b, nil)
}
}
return
diff --git a/mkvtool/utils.go b/mkvtool/utils.go
index 95bdbfb..e60afe8 100644
--- a/mkvtool/utils.go
+++ b/mkvtool/utils.go
@@ -2,12 +2,10 @@ package main
import (
"errors"
- "math/rand"
"os"
"path/filepath"
"regexp"
"strings"
- "time"
)
func queryPath(path string, cb func(string) bool) error {
@@ -50,29 +48,3 @@ func splitPath(p string) (dir, name, ext, namewithoutext string) {
}
return
}
-
-var r = rand.New(rand.NewSource(time.Now().UnixNano()))
-
-func randomN(n int) int {
- return r.Intn(n)
-}
-
-func randomNumber(min, max int) int {
- sub := max - min + 1
- if sub <= 1 {
- return min
- }
- return min + randomN(sub)
-}
-
-func randomStr(l int) string {
- str := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- bytes := []byte(str)
- var result []byte
- lstr := len(str) - 1
- for i := 0; i < l; i++ {
- n := randomNumber(0, lstr)
- result = append(result, bytes[n])
- }
- return string(result)
-}