test: ffmpeg meta and export golden tests
This commit is contained in:
parent
feb4a1f3db
commit
bb48a1e717
4 changed files with 52 additions and 34 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
# imagorvideo
|
# imagorvideo
|
||||||
|
|
||||||
|
[](https://github.com/cshum/imagorvideo/actions/workflows/test.yml)
|
||||||
[](https://hub.docker.com/r/shumc/imagorvideo/)
|
[](https://hub.docker.com/r/shumc/imagorvideo/)
|
||||||
[](https://github.com/cshum/imagorvideo/pkgs/container/imagorvideo)
|
[](https://github.com/cshum/imagorvideo/pkgs/container/imagorvideo)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,6 @@ package ffmpeg
|
||||||
|
|
||||||
// #include "ffmpeg.h"
|
// #include "ffmpeg.h"
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type avError int
|
type avError int
|
||||||
|
|
||||||
|
|
@ -19,19 +15,20 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e avError) errorString() string {
|
func (e avError) errorString() string {
|
||||||
if e == ErrNoMem {
|
switch e {
|
||||||
|
case ErrNoMem:
|
||||||
return "cannot allocate memory"
|
return "cannot allocate memory"
|
||||||
}
|
case ErrTooBig:
|
||||||
if e == ErrTooBig {
|
|
||||||
return "video or cover art size exceeds maximum allowed dimensions"
|
return "video or cover art size exceeds maximum allowed dimensions"
|
||||||
|
case ErrEOF:
|
||||||
|
return "end of file"
|
||||||
|
case ErrDecoderNotFound:
|
||||||
|
return "decoder not found"
|
||||||
|
case ErrInvalidData:
|
||||||
|
return "invalid data found when processing input"
|
||||||
|
default:
|
||||||
|
return "unknown error occurred"
|
||||||
}
|
}
|
||||||
errString := (*C.char)(C.av_malloc(C.AV_ERROR_MAX_STRING_SIZE))
|
|
||||||
if errString == nil {
|
|
||||||
return "cannot allocate memory for error string, error code: " + strconv.Itoa(int(e))
|
|
||||||
}
|
|
||||||
defer C.av_free(unsafe.Pointer(errString))
|
|
||||||
C.av_make_error_string(errString, C.AV_ERROR_MAX_STRING_SIZE, C.int(e))
|
|
||||||
return C.GoString(errString)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e avError) Error() string {
|
func (e avError) Error() string {
|
||||||
|
|
|
||||||
|
|
@ -6,46 +6,61 @@ import (
|
||||||
"github.com/cshum/imagor/vips"
|
"github.com/cshum/imagor/vips"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.uber.org/zap"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var files = []struct {
|
var files = []string{
|
||||||
file string
|
"everybody-betray-me.mkv",
|
||||||
}{
|
"alpha-webm.webm",
|
||||||
{file: "everybody-betray-me.mkv"},
|
"schizo.flv",
|
||||||
{file: "alpha-webm.webm"},
|
"macabre.mp4",
|
||||||
{file: "schizo.flv"},
|
"schizo_0.mp4",
|
||||||
{file: "macabre.mp4"},
|
"schizo_90.mp4",
|
||||||
{file: "schizo_0.mp4"},
|
"schizo_180.mp4",
|
||||||
{file: "schizo_90.mp4"},
|
"schizo_270.mp4",
|
||||||
{file: "schizo_180.mp4"},
|
|
||||||
{file: "schizo_270.mp4"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseDir = "../testdata/"
|
var baseDir = "../testdata/"
|
||||||
|
|
||||||
func TestAVContextMeta(t *testing.T) {
|
func TestAVContextMeta(t *testing.T) {
|
||||||
vips.Startup(nil)
|
vips.Startup(nil)
|
||||||
|
SetFFmpegLogLevel(AVLogDebug)
|
||||||
|
logger := zap.NewExample()
|
||||||
|
SetLogging(nil)
|
||||||
|
SetLogging(func(level AVLogLevel, message string) {
|
||||||
|
message = strings.TrimSuffix(message, "\n")
|
||||||
|
switch level {
|
||||||
|
case AVLogTrace, AVLogDebug, AVLogVerbose:
|
||||||
|
logger.Debug("ffmpeg", zap.String("log", message))
|
||||||
|
case AVLogInfo:
|
||||||
|
logger.Info("ffmpeg", zap.String("log", message))
|
||||||
|
case AVLogWarning, AVLogError, AVLogFatal, AVLogPanic:
|
||||||
|
logger.Warn("ffmpeg", zap.String("log", message))
|
||||||
|
}
|
||||||
|
})
|
||||||
require.NoError(t, os.MkdirAll(baseDir+"golden/meta", 0755))
|
require.NoError(t, os.MkdirAll(baseDir+"golden/meta", 0755))
|
||||||
require.NoError(t, os.MkdirAll(baseDir+"golden/result", 0755))
|
require.NoError(t, os.MkdirAll(baseDir+"golden/result", 0755))
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
for _, tt := range files {
|
for _, filename := range files {
|
||||||
t.Run(tt.file, func(t *testing.T) {
|
t.Run(filename, func(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
path := baseDir + tt.file
|
path := baseDir + filename
|
||||||
reader, err := os.Open(path)
|
reader, err := os.Open(path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
stats, err := os.Stat(path)
|
stats, err := os.Stat(path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
av, err := LoadAVContext(ctx, reader, stats.Size())
|
av, err := LoadAVContext(ctx, reader, stats.Size())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
defer av.Close()
|
||||||
|
|
||||||
meta := av.Metadata()
|
meta := av.Metadata()
|
||||||
metaBuf, err := json.Marshal(meta)
|
metaBuf, err := json.Marshal(meta)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
goldenFile := baseDir + "golden/meta/" + tt.file + ".meta.json"
|
goldenFile := baseDir + "golden/meta/" + filename + ".meta.json"
|
||||||
if curr, err := os.ReadFile(goldenFile); err == nil {
|
if curr, err := os.ReadFile(goldenFile); err == nil {
|
||||||
assert.Equal(t, string(curr), string(metaBuf))
|
assert.Equal(t, string(curr), string(metaBuf))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -62,7 +77,7 @@ func TestAVContextMeta(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
buf, err = img.ExportJpeg(nil)
|
buf, err = img.ExportJpeg(nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
goldenFile = baseDir + "golden/export/" + tt.file + ".jpg"
|
goldenFile = baseDir + "golden/export/" + filename + ".jpg"
|
||||||
if curr, err := os.ReadFile(goldenFile); err == nil {
|
if curr, err := os.ReadFile(goldenFile); err == nil {
|
||||||
assert.True(t, reflect.DeepEqual(curr, buf))
|
assert.True(t, reflect.DeepEqual(curr, buf))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -72,3 +87,12 @@ func TestAVContextMeta(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestErrors(t *testing.T) {
|
||||||
|
assert.Equal(t, "ffmpeg: cannot allocate memory", ErrNoMem.Error())
|
||||||
|
assert.Equal(t, "ffmpeg: end of file", ErrEOF.Error())
|
||||||
|
assert.Equal(t, "ffmpeg: unknown error occurred", ErrUnknown.Error())
|
||||||
|
assert.Equal(t, "ffmpeg: decoder not found", ErrDecoderNotFound.Error())
|
||||||
|
assert.Equal(t, "ffmpeg: invalid data found when processing input", ErrInvalidData.Error())
|
||||||
|
assert.Equal(t, "ffmpeg: video or cover art size exceeds maximum allowed dimensions", ErrTooBig.Error())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@ var (
|
||||||
onceLogging sync.Once
|
onceLogging sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
func logLevel() AVLogLevel {
|
|
||||||
return AVLogLevel(C.av_log_get_level())
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFFmpegLogLevel allows you to change the log level from the default (AVLogInfo).
|
// SetFFmpegLogLevel allows you to change the log level from the default (AVLogInfo).
|
||||||
func SetFFmpegLogLevel(logLevel AVLogLevel) {
|
func SetFFmpegLogLevel(logLevel AVLogLevel) {
|
||||||
C.av_log_set_level(C.int(logLevel))
|
C.av_log_set_level(C.int(logLevel))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue