[chore] update go ffmpreg to v0.6.0 (#3515)
* pull in go-ffmpreg v0.6.0 * add code comment * grrr linter * set empty module name when calling ffmpeg / ffprobe
This commit is contained in:
parent
6f4cb2f14e
commit
b84637801a
2
go.mod
2
go.mod
|
@ -12,7 +12,7 @@ require (
|
|||
codeberg.org/gruf/go-debug v1.3.0
|
||||
codeberg.org/gruf/go-errors/v2 v2.3.2
|
||||
codeberg.org/gruf/go-fastcopy v1.1.3
|
||||
codeberg.org/gruf/go-ffmpreg v0.4.2
|
||||
codeberg.org/gruf/go-ffmpreg v0.6.0
|
||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf
|
||||
codeberg.org/gruf/go-kv v1.6.5
|
||||
codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f
|
||||
|
|
|
@ -46,8 +46,8 @@ codeberg.org/gruf/go-fastcopy v1.1.3 h1:Jo9VTQjI6KYimlw25PPc7YLA3Xm+XMQhaHwKnM7x
|
|||
codeberg.org/gruf/go-fastcopy v1.1.3/go.mod h1:GDDYR0Cnb3U/AIfGM3983V/L+GN+vuwVMvrmVABo21s=
|
||||
codeberg.org/gruf/go-fastpath/v2 v2.0.0 h1:iAS9GZahFhyWEH0KLhFEJR+txx1ZhMXxYzu2q5Qo9c0=
|
||||
codeberg.org/gruf/go-fastpath/v2 v2.0.0/go.mod h1:3pPqu5nZjpbRrOqvLyAK7puS1OfEtQvjd6342Cwz56Q=
|
||||
codeberg.org/gruf/go-ffmpreg v0.4.2 h1:HKkPapm/PWkxsnUdjyQOGpwl5Qoa2EBrUQ09s4R4/FA=
|
||||
codeberg.org/gruf/go-ffmpreg v0.4.2/go.mod h1:Ar5nbt3tB2Wr0uoaqV3wDBNwAx+H+AB/mV7Kw7NlZTI=
|
||||
codeberg.org/gruf/go-ffmpreg v0.6.0 h1:/cfUJ9bFKEoXT9LDYZy3eZ0HF60YWcO+0nGciepJKMw=
|
||||
codeberg.org/gruf/go-ffmpreg v0.6.0/go.mod h1:Ar5nbt3tB2Wr0uoaqV3wDBNwAx+H+AB/mV7Kw7NlZTI=
|
||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf h1:84s/ii8N6lYlskZjHH+DG6jyia8w2mXMZlRwFn8Gs3A=
|
||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf/go.mod h1:zZAICsp5rY7+hxnws2V0ePrWxE0Z2Z/KXcN3p/RQCfk=
|
||||
codeberg.org/gruf/go-kv v1.6.5 h1:ttPf0NA8F79pDqBttSudPTVCZmGncumeNIxmeM9ztz0=
|
||||
|
|
|
@ -181,6 +181,10 @@ func ffmpeg(ctx context.Context, inpath string, outpath string, args ...string)
|
|||
}
|
||||
fscfg = fscfg.WithFSMount(shared, path.Dir(inpath))
|
||||
|
||||
// Set anonymous module name.
|
||||
modcfg = modcfg.WithName("")
|
||||
|
||||
// Update with prepared fs config.
|
||||
return modcfg.WithFSConfig(fscfg)
|
||||
},
|
||||
})
|
||||
|
@ -247,6 +251,10 @@ func ffprobe(ctx context.Context, filepath string) (*result, error) {
|
|||
}
|
||||
fscfg = fscfg.WithFSMount(in, path.Dir(filepath))
|
||||
|
||||
// Set anonymous module name.
|
||||
modcfg = modcfg.WithName("")
|
||||
|
||||
// Update with prepared fs config.
|
||||
return modcfg.WithFSConfig(fscfg)
|
||||
},
|
||||
})
|
||||
|
|
|
@ -21,6 +21,7 @@ package ffmpeg
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"codeberg.org/gruf/go-ffmpreg/wasm"
|
||||
)
|
||||
|
@ -35,12 +36,25 @@ var ffmpegRunner runner
|
|||
// prepares the runner to only allow max given concurrent running instances.
|
||||
func InitFfmpeg(ctx context.Context, max int) error {
|
||||
ffmpegRunner.Init(max)
|
||||
return compileFfmpeg(ctx)
|
||||
return initWASM(ctx)
|
||||
}
|
||||
|
||||
// Ffmpeg runs the given arguments with an instance of ffmpeg.
|
||||
func Ffmpeg(ctx context.Context, args Args) (uint32, error) {
|
||||
return ffmpegRunner.Run(ctx, func() (uint32, error) {
|
||||
return wasm.Run(ctx, runtime, ffmpeg, args)
|
||||
|
||||
// Load WASM rt and module.
|
||||
ffmpreg := ffmpreg.Load()
|
||||
if ffmpreg == nil {
|
||||
return 0, errors.New("wasm not initialized")
|
||||
}
|
||||
|
||||
// Call into ffmpeg.
|
||||
args.Name = "ffmpeg"
|
||||
return wasm.Run(ctx,
|
||||
ffmpreg.run,
|
||||
ffmpreg.mod,
|
||||
args,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package ffmpeg
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"codeberg.org/gruf/go-ffmpreg/wasm"
|
||||
)
|
||||
|
@ -35,12 +36,25 @@ var ffprobeRunner runner
|
|||
// prepares the runner to only allow max given concurrent running instances.
|
||||
func InitFfprobe(ctx context.Context, max int) error {
|
||||
ffprobeRunner.Init(max)
|
||||
return compileFfprobe(ctx)
|
||||
return initWASM(ctx)
|
||||
}
|
||||
|
||||
// Ffprobe runs the given arguments with an instance of ffprobe.
|
||||
func Ffprobe(ctx context.Context, args Args) (uint32, error) {
|
||||
return ffprobeRunner.Run(ctx, func() (uint32, error) {
|
||||
return wasm.Run(ctx, runtime, ffprobe, args)
|
||||
|
||||
// Load WASM rt and module.
|
||||
ffmpreg := ffmpreg.Load()
|
||||
if ffmpreg == nil {
|
||||
return 0, errors.New("wasm not initialized")
|
||||
}
|
||||
|
||||
// Call into ffprobe.
|
||||
args.Name = "ffprobe"
|
||||
return wasm.Run(ctx,
|
||||
ffmpreg.run,
|
||||
ffmpreg.mod,
|
||||
args,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -22,72 +22,27 @@ package ffmpeg
|
|||
import (
|
||||
"context"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
ffmpeglib "codeberg.org/gruf/go-ffmpreg/embed/ffmpeg"
|
||||
ffprobelib "codeberg.org/gruf/go-ffmpreg/embed/ffprobe"
|
||||
"codeberg.org/gruf/go-ffmpreg/embed"
|
||||
"codeberg.org/gruf/go-ffmpreg/wasm"
|
||||
"github.com/tetratelabs/wazero"
|
||||
)
|
||||
|
||||
var (
|
||||
// shared WASM runtime instance.
|
||||
runtime wazero.Runtime
|
||||
// ffmpreg is a concurrency-safe pointer
|
||||
// to our necessary WebAssembly runtime
|
||||
// and compiled ffmpreg module instance.
|
||||
var ffmpreg atomic.Pointer[struct {
|
||||
run wazero.Runtime
|
||||
mod wazero.CompiledModule
|
||||
}]
|
||||
|
||||
// ffmpeg / ffprobe compiled WASM.
|
||||
ffmpeg wazero.CompiledModule
|
||||
ffprobe wazero.CompiledModule
|
||||
)
|
||||
|
||||
// compileFfmpeg ensures the ffmpeg WebAssembly has been
|
||||
// pre-compiled into memory. If already compiled is a no-op.
|
||||
func compileFfmpeg(ctx context.Context) error {
|
||||
if ffmpeg != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure runtime already initialized.
|
||||
if err := initRuntime(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compile the ffmpeg WebAssembly module into memory.
|
||||
cmod, err := runtime.CompileModule(ctx, ffmpeglib.B)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set module.
|
||||
ffmpeg = cmod
|
||||
return nil
|
||||
}
|
||||
|
||||
// compileFfprobe ensures the ffprobe WebAssembly has been
|
||||
// pre-compiled into memory. If already compiled is a no-op.
|
||||
func compileFfprobe(ctx context.Context) error {
|
||||
if ffprobe != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure runtime already initialized.
|
||||
if err := initRuntime(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compile the ffprobe WebAssembly module into memory.
|
||||
cmod, err := runtime.CompileModule(ctx, ffprobelib.B)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set module.
|
||||
ffprobe = cmod
|
||||
return nil
|
||||
}
|
||||
|
||||
// initRuntime initializes the global wazero.Runtime,
|
||||
// if already initialized this function is a no-op.
|
||||
func initRuntime(ctx context.Context) (err error) {
|
||||
if runtime != nil {
|
||||
// initWASM safely prepares new WebAssembly runtime
|
||||
// and compiles ffmpreg module instance, if the global
|
||||
// pointer has not been already. else, is a no-op.
|
||||
func initWASM(ctx context.Context) error {
|
||||
if ffmpreg.Load() != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -105,7 +60,59 @@ func initRuntime(ctx context.Context) (err error) {
|
|||
cfg = cfg.WithCompilationCache(cache)
|
||||
}
|
||||
|
||||
var (
|
||||
run wazero.Runtime
|
||||
mod wazero.CompiledModule
|
||||
err error
|
||||
set bool
|
||||
)
|
||||
|
||||
defer func() {
|
||||
if err == nil && set {
|
||||
// Drop binary.
|
||||
embed.B = nil
|
||||
return
|
||||
}
|
||||
|
||||
// Close module.
|
||||
if !isNil(mod) {
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
// Close runtime.
|
||||
if !isNil(run) {
|
||||
run.Close(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
// Initialize new runtime from config.
|
||||
runtime, err = wasm.NewRuntime(ctx, cfg)
|
||||
return
|
||||
run, err = wasm.NewRuntime(ctx, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compile ffmpreg WebAssembly into memory.
|
||||
mod, err = run.CompileModule(ctx, embed.B)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Try set global WASM runtime and module,
|
||||
// or if beaten to it defer will handle close.
|
||||
set = ffmpreg.CompareAndSwap(nil, &struct {
|
||||
run wazero.Runtime
|
||||
mod wazero.CompiledModule
|
||||
}{
|
||||
run: run,
|
||||
mod: mod,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isNil will safely check if 'v' is nil without
|
||||
// dealing with weird Go interface nil bullshit.
|
||||
func isNil(i interface{}) bool {
|
||||
type eface struct{ Type, Data unsafe.Pointer }
|
||||
return (*eface)(unsafe.Pointer(&i)).Data == nil
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -1,25 +0,0 @@
|
|||
package ffmpeg
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Check for WASM source file path.
|
||||
path := os.Getenv("FFMPEG_WASM")
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
// Read file into memory.
|
||||
B, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed ffmpeg.wasm
|
||||
var B []byte
|
Binary file not shown.
Binary file not shown.
|
@ -1,25 +0,0 @@
|
|||
package ffprobe
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Check for WASM source file path.
|
||||
path := os.Getenv("FFPROBE_WASM")
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
// Read file into memory.
|
||||
B, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed ffprobe.wasm
|
||||
var B []byte
|
|
@ -0,0 +1,39 @@
|
|||
package embed
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
_ "embed"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
|
||||
if path := os.Getenv("FFMPREG_WASM"); path != "" {
|
||||
// Read file into memory.
|
||||
B, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap bytes in reader.
|
||||
b := bytes.NewReader(B)
|
||||
|
||||
// Create unzipper from reader.
|
||||
gz, err := gzip.NewReader(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Extract gzipped binary.
|
||||
B, err = io.ReadAll(gz)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed ffmpreg.wasm.gz
|
||||
var B []byte
|
|
@ -14,6 +14,11 @@ import (
|
|||
// wazero.Runtime on module instantiation.
|
||||
type Args struct {
|
||||
|
||||
// Program name, depending on the
|
||||
// module being run this may or may
|
||||
// not be necessary.
|
||||
Name string
|
||||
|
||||
// Optional further module configuration function.
|
||||
// (e.g. to mount filesystem dir, set env vars, etc).
|
||||
Config func(wazero.ModuleConfig) wazero.ModuleConfig
|
||||
|
@ -39,7 +44,7 @@ func Run(
|
|||
|
||||
// Prefix arguments with module name.
|
||||
cargs := make([]string, len(args.Args)+1)
|
||||
cargs[0] = module.Name()
|
||||
cargs[0] = args.Name
|
||||
copy(cargs[1:], args.Args)
|
||||
|
||||
// Prepare new module configuration.
|
||||
|
|
|
@ -24,10 +24,9 @@ codeberg.org/gruf/go-fastcopy
|
|||
# codeberg.org/gruf/go-fastpath/v2 v2.0.0
|
||||
## explicit; go 1.14
|
||||
codeberg.org/gruf/go-fastpath/v2
|
||||
# codeberg.org/gruf/go-ffmpreg v0.4.2
|
||||
# codeberg.org/gruf/go-ffmpreg v0.6.0
|
||||
## explicit; go 1.22.0
|
||||
codeberg.org/gruf/go-ffmpreg/embed/ffmpeg
|
||||
codeberg.org/gruf/go-ffmpreg/embed/ffprobe
|
||||
codeberg.org/gruf/go-ffmpreg/embed
|
||||
codeberg.org/gruf/go-ffmpreg/wasm
|
||||
# codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf
|
||||
## explicit; go 1.21
|
||||
|
|
Loading…
Reference in New Issue