77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package ffmpeg
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os/exec"
|
|
)
|
|
|
|
type VideoProcessor interface {
|
|
GenerateThumbnail(videoData []byte) ([]byte, error)
|
|
TrimVideo(videoData []byte, maxDuration int) ([]byte, error)
|
|
}
|
|
|
|
type videoProcessor struct {
|
|
}
|
|
|
|
func NewVideoProcessor() VideoProcessor {
|
|
return &videoProcessor{}
|
|
}
|
|
|
|
func (vp *videoProcessor) GenerateThumbnail(videoData []byte) ([]byte, error) {
|
|
cmd := exec.Command("ffmpeg",
|
|
"-i", "pipe:0",
|
|
"-ss", "00:00:01",
|
|
"-vframes", "1",
|
|
"-q:v", "2",
|
|
"-f", "image2pipe",
|
|
"-c:v", "mjpeg",
|
|
"pipe:1",
|
|
)
|
|
|
|
cmd.Stdin = bytes.NewReader(videoData)
|
|
var output bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
cmd.Stdout = &output
|
|
cmd.Stderr = &stderr
|
|
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ffmpeg failed: %s, error: %w", stderr.String(), err)
|
|
}
|
|
|
|
if output.Len() == 0 {
|
|
return nil, fmt.Errorf("thumbnail generation produced empty output")
|
|
}
|
|
|
|
return output.Bytes(), nil
|
|
}
|
|
|
|
func (vp *videoProcessor) TrimVideo(videoData []byte, maxDuration int) ([]byte, error) {
|
|
// Просто обрезаем видео без проверки длительности
|
|
cmd := exec.Command("ffmpeg",
|
|
"-i", "pipe:0",
|
|
"-t", fmt.Sprintf("%d", maxDuration),
|
|
"-c", "copy",
|
|
"-f", "mp4",
|
|
"pipe:1",
|
|
)
|
|
|
|
cmd.Stdin = bytes.NewReader(videoData)
|
|
var output bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
cmd.Stdout = &output
|
|
cmd.Stderr = &stderr
|
|
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ffmpeg trim failed: %s, error: %w", stderr.String(), err)
|
|
}
|
|
|
|
if output.Len() == 0 {
|
|
return nil, fmt.Errorf("trimmed video is empty")
|
|
}
|
|
|
|
return output.Bytes(), nil
|
|
}
|