WIP
This commit is contained in:
parent
08ba577b27
commit
3ba52e60cf
114
.github/workflows/build-release.yml
vendored
Normal file
114
.github/workflows/build-release.yml
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
name: build release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '[0-9]+.[0-9]+.[0-9]+'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.13.0'
|
||||
|
||||
- name: Build
|
||||
run: make -j $(nproc) compile VERSION=${{ github.ref }}
|
||||
|
||||
- name: create release
|
||||
id: create_release
|
||||
uses: actions/create-release@latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: darwin-386
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-darwin-386
|
||||
asset_name: ${{ github.event.repository.name }}-darwin-386
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: darwin-amd64
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-darwin-amd64
|
||||
asset_name: ${{ github.event.repository.name }}-darwin-amd64
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: freebsd-386
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-freebsd-386
|
||||
asset_name: ${{ github.event.repository.name }}-freebsd-386
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: freebsd-amd64
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-freebsd-amd64
|
||||
asset_name: ${{ github.event.repository.name }}-freebsd-amd64
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: linux-386
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-linux-386
|
||||
asset_name: ${{ github.event.repository.name }}-linux-386
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: linux-amd64
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-linux-amd64
|
||||
asset_name: ${{ github.event.repository.name }}-linux-amd64
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: windows-386
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-windows-386.exe
|
||||
asset_name: ${{ github.event.repository.name }}-windows-386.exe
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: windows-amd64
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/${{ github.event.repository.name }}-windows-amd64.exe
|
||||
asset_name: ${{ github.event.repository.name }}-windows-amd64.exe
|
||||
asset_content_type: application/octet-stream
|
||||
|
21
Makefile
21
Makefile
@ -1,16 +1,19 @@
|
||||
NAME=range-gen
|
||||
VERSION=0.1.0
|
||||
GOCMD=go
|
||||
LDFLAGS:="$(LDFLAGS) -X 'main.Version=$(VERSION)'"
|
||||
GOBUILD=$(GOCMD) build -ldflags=$(LDFLAGS)
|
||||
SRCMAIN=.
|
||||
BINDIR=bin
|
||||
BIN=$(BINDIR)/$(NAME)
|
||||
PREFIX=/usr
|
||||
NAME = range-gen
|
||||
VERSION = dev_$(shell date +%F_%T)
|
||||
GOCMD = go
|
||||
LDFLAGS := "$(LDFLAGS) -X 'main.Version=$(VERSION)'"
|
||||
GOBUILD = $(GOCMD) build -ldflags=$(LDFLAGS)
|
||||
SRCMAIN = .
|
||||
BINDIR = bin
|
||||
BIN = $(BINDIR)/$(NAME)
|
||||
PREFIX = /usr
|
||||
|
||||
.PHONY: all prep build check-build freebsd-386 darwin-386 linux-386 windows-386 freebsd-amd64 darwin-amd64 linux-amd64 windows-amd64 compile install check-install uninstall clean
|
||||
|
||||
all: build
|
||||
|
||||
prep: clean
|
||||
go mod init; go mod tidy
|
||||
mkdir $(BINDIR)
|
||||
|
||||
build: prep
|
||||
|
40
args.go
40
args.go
@ -3,7 +3,10 @@ package main
|
||||
import (
|
||||
"github.com/juju/gnuflag"
|
||||
|
||||
"range-gen/output"
|
||||
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -16,12 +19,28 @@ var (
|
||||
|
||||
ArgJobs int = 0
|
||||
ArgDefaultNoiseLevel int = 0
|
||||
|
||||
ArgVersion bool = false
|
||||
ArgHelp bool = false
|
||||
)
|
||||
|
||||
func Use(vals ...interface{}) {
|
||||
for _, val := range vals {
|
||||
_ = val
|
||||
}
|
||||
func printHelp() {
|
||||
output.Println("Сreates a list of scene ranges based on a set of frames from the video")
|
||||
output.Println("")
|
||||
output.Println("Usage: range-gen [option]... <input_dir> <output_file> <threshold>")
|
||||
output.Println("input_dir Directory with png images")
|
||||
output.Println("output_file Range list file")
|
||||
output.Println("threshold Image similarity threshold (0-1024)")
|
||||
output.Println("")
|
||||
output.Println("Options:")
|
||||
output.Println(" -j, --jobs N Allow N jobs at once")
|
||||
output.Println(" -n, --noise Default noise level for each range")
|
||||
output.Println(" -h, --help Show this page")
|
||||
output.Println(" -v, --version Show version")
|
||||
}
|
||||
|
||||
func printVersion() {
|
||||
output.Println("multini ", Version)
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -29,11 +48,24 @@ func init() {
|
||||
gnuflag.IntVar(&ArgJobs, "j", 0, "")
|
||||
gnuflag.IntVar(&ArgDefaultNoiseLevel, "noise", -1, "")
|
||||
gnuflag.IntVar(&ArgDefaultNoiseLevel, "n", -1, "")
|
||||
gnuflag.BoolVar(&ArgVersion, "version", false, "")
|
||||
gnuflag.BoolVar(&ArgVersion, "v", false, "")
|
||||
gnuflag.BoolVar(&ArgHelp, "help", false, "")
|
||||
gnuflag.BoolVar(&ArgHelp, "h", false, "")
|
||||
}
|
||||
|
||||
func parseArgs() error {
|
||||
gnuflag.Parse(false)
|
||||
|
||||
switch {
|
||||
case ArgHelp:
|
||||
printHelp()
|
||||
os.Exit(EXIT_SUCCESS)
|
||||
case ArgVersion:
|
||||
printVersion()
|
||||
os.Exit(EXIT_SUCCESS)
|
||||
}
|
||||
|
||||
for i := 0; i < 3 && i < gnuflag.NArg(); i++ {
|
||||
switch i {
|
||||
case 0:
|
||||
|
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
||||
module range-gen
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||
github.com/dsoprea/go-perceptualhash v0.0.0-20200804060033-5ef3a3d0c14b
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
)
|
16
go.sum
Normal file
16
go.sum
Normal file
@ -0,0 +1,16 @@
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||
github.com/dsoprea/go-perceptualhash v0.0.0-20200804060033-5ef3a3d0c14b h1:MvVsQ3fIkIpkUwphIPzjsuJGNjYQaPMAn7nXtet6Jcc=
|
||||
github.com/dsoprea/go-perceptualhash v0.0.0-20200804060033-5ef3a3d0c14b/go.mod h1:mOZww7GHNRuvbz9vRejK7aGUgZU6Z+dleJ6PrFCDieE=
|
||||
github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
92
main.go
92
main.go
@ -5,9 +5,14 @@ import (
|
||||
"image"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
_ "image/png"
|
||||
|
||||
@ -25,12 +30,14 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
Version string = "dev"
|
||||
|
||||
hashes map[string]string
|
||||
names []string
|
||||
)
|
||||
|
||||
func main() {
|
||||
output.SetEndOfLineNative()
|
||||
closeHandler() // Ctrl+C
|
||||
|
||||
if err := parseArgs(); err != nil {
|
||||
output.Errorln(err)
|
||||
@ -49,19 +56,73 @@ func main() {
|
||||
os.Exit(EXIT_DIR_READ_ERR)
|
||||
}
|
||||
|
||||
if ArgJobs == 0 {
|
||||
ArgJobs = runtime.NumCPU()
|
||||
}
|
||||
runtime.GOMAXPROCS(ArgJobs)
|
||||
|
||||
hashes, names := calcHashes(files)
|
||||
|
||||
ranges := calcRanges(hashes, names, Threshold)
|
||||
|
||||
writeRanges(ranges)
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
//wg.Add(1)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
os.Exit(EXIT_SUCCESS)
|
||||
}
|
||||
|
||||
func closeHandler() {
|
||||
interrupt := make(chan os.Signal, 2)
|
||||
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-interrupt
|
||||
output.Println("Closed by SIGINT")
|
||||
os.Exit(EXIT_SUCCESS)
|
||||
}()
|
||||
}
|
||||
|
||||
func calcHashes(files []os.FileInfo) (map[string]string, []string) {
|
||||
var hashes map[string]string
|
||||
var keys []string
|
||||
var err error
|
||||
|
||||
hashes = make(map[string]string)
|
||||
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.HasSuffix(file.Name(), ".png") {
|
||||
names = append(names, file.Name())
|
||||
hashes[file.Name()], err = calchash(ArgInput + file.Name())
|
||||
keys = append(keys, file.Name())
|
||||
hashes[file.Name()], err = calcHash(filepath.Join(ArgInput, file.Name()))
|
||||
|
||||
if err != nil {
|
||||
output.Errorln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(names)
|
||||
sort.Strings(keys)
|
||||
return hashes, keys
|
||||
}
|
||||
|
||||
func calcHash(filepath string) (string, error) {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
image, _, err := image.Decode(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return blockhash.NewBlockhash(image, 16).Hexdigest(), nil
|
||||
}
|
||||
|
||||
func calcRanges(hashes map[string]string, names []string, Threshold int) string {
|
||||
var ranges strings.Builder
|
||||
var prevHash string = ""
|
||||
var dist int = 0
|
||||
@ -86,12 +147,16 @@ func main() {
|
||||
}
|
||||
ranges.WriteString(startName + "\t" + names[len(names)-1] + rangeNoise + output.EOL())
|
||||
|
||||
return ranges.String()
|
||||
}
|
||||
|
||||
func writeRanges(ranges string) {
|
||||
mode := os.FileMode(int(0644))
|
||||
targetFile, err := os.OpenFile(ArgOutput, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
|
||||
defer targetFile.Close()
|
||||
if err == nil {
|
||||
datawriter := bufio.NewWriter(targetFile)
|
||||
_, err = datawriter.WriteString(ranges.String())
|
||||
_, err = datawriter.WriteString(ranges)
|
||||
if err == nil {
|
||||
err = datawriter.Flush()
|
||||
}
|
||||
@ -101,23 +166,6 @@ func main() {
|
||||
output.Errorln(err)
|
||||
os.Exit(EXIT_FILE_WRITE_ERR)
|
||||
}
|
||||
|
||||
os.Exit(EXIT_SUCCESS)
|
||||
}
|
||||
|
||||
func calchash(filepath string) (string, error) {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
image, _, err := image.Decode(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return blockhash.NewBlockhash(image, 16).Hexdigest(), nil
|
||||
}
|
||||
|
||||
func hammingDistance(prev, cur string) int {
|
||||
|
@ -15,6 +15,10 @@ var (
|
||||
stderr *log.Logger = log.New(os.Stderr, "", 0)
|
||||
)
|
||||
|
||||
func init() {
|
||||
SetEndOfLineNative()
|
||||
}
|
||||
|
||||
func SetQuiet(enabled bool) {
|
||||
if enabled {
|
||||
stdout = devNull
|
||||
|
Loading…
x
Reference in New Issue
Block a user