diff --git a/README.md b/README.md index b7cc426..432e95f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # imagorvideo +[![Test Status](https://github.com/cshum/imagorvideo/workflows/test/badge.svg)](https://github.com/cshum/imagorvideo/actions/workflows/test.yml) [![Docker Hub](https://img.shields.io/badge/docker-shumc/imagorvideo-blue.svg)](https://hub.docker.com/r/shumc/imagorvideo/) [![GitHub Container Registry](https://ghcr-badge.herokuapp.com/cshum/imagorvideo/latest_tag?trim=major&label=ghcr.io&ignore=next,master&color=%23007ec6)](https://github.com/cshum/imagorvideo/pkgs/container/imagorvideo) diff --git a/ffmpeg/errors.go b/ffmpeg/errors.go index 128bc87..42c4685 100644 --- a/ffmpeg/errors.go +++ b/ffmpeg/errors.go @@ -2,10 +2,6 @@ package ffmpeg // #include "ffmpeg.h" import "C" -import ( - "strconv" - "unsafe" -) type avError int @@ -19,19 +15,20 @@ const ( ) func (e avError) errorString() string { - if e == ErrNoMem { + switch e { + case ErrNoMem: return "cannot allocate memory" - } - if e == ErrTooBig { + case ErrTooBig: 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 { diff --git a/ffmpeg/ffmpeg_test.go b/ffmpeg/ffmpeg_test.go index f0a88e1..6e6a711 100644 --- a/ffmpeg/ffmpeg_test.go +++ b/ffmpeg/ffmpeg_test.go @@ -6,46 +6,61 @@ import ( "github.com/cshum/imagor/vips" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap" "os" "reflect" + "strings" "testing" ) -var files = []struct { - file string -}{ - {file: "everybody-betray-me.mkv"}, - {file: "alpha-webm.webm"}, - {file: "schizo.flv"}, - {file: "macabre.mp4"}, - {file: "schizo_0.mp4"}, - {file: "schizo_90.mp4"}, - {file: "schizo_180.mp4"}, - {file: "schizo_270.mp4"}, +var files = []string{ + "everybody-betray-me.mkv", + "alpha-webm.webm", + "schizo.flv", + "macabre.mp4", + "schizo_0.mp4", + "schizo_90.mp4", + "schizo_180.mp4", + "schizo_270.mp4", } var baseDir = "../testdata/" func TestAVContextMeta(t *testing.T) { 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/result", 0755)) t.Parallel() - for _, tt := range files { - t.Run(tt.file, func(t *testing.T) { + for _, filename := range files { + t.Run(filename, func(t *testing.T) { ctx := context.Background() - path := baseDir + tt.file + path := baseDir + filename reader, err := os.Open(path) require.NoError(t, err) stats, err := os.Stat(path) require.NoError(t, err) av, err := LoadAVContext(ctx, reader, stats.Size()) require.NoError(t, err) + defer av.Close() meta := av.Metadata() metaBuf, err := json.Marshal(meta) 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 { assert.Equal(t, string(curr), string(metaBuf)) } else { @@ -62,7 +77,7 @@ func TestAVContextMeta(t *testing.T) { require.NoError(t, err) buf, err = img.ExportJpeg(nil) 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 { assert.True(t, reflect.DeepEqual(curr, buf)) } 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()) +} diff --git a/ffmpeg/logging.go b/ffmpeg/logging.go index ffa5a05..c8453cd 100644 --- a/ffmpeg/logging.go +++ b/ffmpeg/logging.go @@ -27,10 +27,6 @@ var ( 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). func SetFFmpegLogLevel(logLevel AVLogLevel) { C.av_log_set_level(C.int(logLevel))