Files
neo/helper/media_convert.go

75 lines
1.9 KiB
Go

package helper
import (
"bytes"
"fmt"
"os/exec"
"github.com/davidbyttow/govips/v2/vips"
)
func ConvertImageToWebp(imgData []byte) ([]byte, error) {
img, err := vips.NewImageFromBuffer(imgData)
if err != nil {
return nil, fmt.Errorf("failed to load image: %w", err)
}
defer img.Close()
if !img.HasAlpha() {
if err := img.AddAlpha(); err != nil {
return nil, fmt.Errorf("failed to add alpha: %w", err)
}
}
if err := img.ThumbnailWithSize(512, 512, vips.InterestingNone, vips.SizeBoth); err != nil {
return nil, fmt.Errorf("failed to resize: %w", err)
}
// Center in 512x512 canvas with transparent background (fit: contain)
w, h := img.Width(), img.Height()
if w != 512 || h != 512 {
left := (512 - w) / 2
top := (512 - h) / 2
if err := img.EmbedBackgroundRGBA(left, top, 512, 512, &vips.ColorRGBA{R: 0, G: 0, B: 0, A: 0}); err != nil {
return nil, fmt.Errorf("failed to embed: %w", err)
}
}
webpBuf, _, err := img.ExportWebp(&vips.WebpExportParams{
Quality: 100,
Lossless: false,
ReductionEffort: 6,
})
if err != nil {
return nil, fmt.Errorf("failed to export webp: %w", err)
}
return webpBuf, nil
}
func ConvertVideoToWebp(vidData []byte) ([]byte, error) {
ffmpegCmd := exec.Command("ffmpeg",
"-y", "-hide_banner", "-loglevel", "error",
"-i", "pipe:0",
"-ss", "00:00:00", "-t", "00:00:15",
"-vcodec", "libwebp",
"-vf", "fps=10,scale=720:-1:flags=lanczos:force_original_aspect_ratio=increase,crop=512:512,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1",
"-loop", "0",
"-preset", "default",
"-an",
"-f", "webp", "pipe:1",
)
ffmpegCmd.Stdin = bytes.NewReader(vidData)
var outBuf bytes.Buffer
var stderr bytes.Buffer
ffmpegCmd.Stdout = &outBuf
ffmpegCmd.Stderr = &stderr
if err := ffmpegCmd.Run(); err != nil {
return nil, fmt.Errorf("ffmpeg direct convert failed: %w, stderr: %s", err, stderr.String())
}
return outBuf.Bytes(), nil
}