Move ffmpeg service to adapters

This commit is contained in:
2025-08-12 14:30:48 +03:00
parent bb3247d391
commit 03106830e5
5 changed files with 27 additions and 16 deletions

View File

@@ -6,26 +6,28 @@ import (
"os/exec" "os/exec"
) )
type FileConverter struct { const ffmpegExecutable = "ffmpeg"
type FfmpegConverter struct {
} }
func NewFileConverter() *FileConverter { func NewFfmpegConverter() *FfmpegConverter {
return &FileConverter{} return &FfmpegConverter{}
} }
func (c *FileConverter) Convert(src, dest string) error { func (c *FfmpegConverter) Convert(src, dest string) error {
// Проверяем существование исходного файла // Проверяем существование исходного файла
if _, err := os.Stat(src); os.IsNotExist(err) { if _, err := os.Stat(src); os.IsNotExist(err) {
return fmt.Errorf("input file does not exist: %s", src) return fmt.Errorf("input file does not exist: %s", src)
} }
// Проверяем, что ffmpeg доступен в системе // Проверяем, что ffmpeg доступен в системе
if _, err := exec.LookPath("ffmpeg"); err != nil { if _, err := exec.LookPath(ffmpegExecutable); err != nil {
return fmt.Errorf("ffmpeg not found in PATH: %w", err) return fmt.Errorf("ffmpeg not found in PATH: %w", err)
} }
// Создаем команду ffmpeg для конвертации в OGG // Создаем команду ffmpeg для конвертации в OGG
cmd := exec.Command("ffmpeg", cmd := exec.Command(ffmpegExecutable,
"-i", src, // входной файл "-i", src, // входной файл
"-c:a", "libvorbis", // кодек Vorbis для OGG "-c:a", "libvorbis", // кодек Vorbis для OGG
"-q:a", "4", // качество аудио (0-10, где 4 - хорошее качество) "-q:a", "4", // качество аудио (0-10, где 4 - хорошее качество)

View File

@@ -3,6 +3,6 @@ package contract
type ObjectStorage interface { type ObjectStorage interface {
} }
type FileConverter interface { type AudioFileConverter interface {
Convert(src, dest string) error Convert(src, dest string) error
} }

View File

@@ -15,6 +15,7 @@ import (
"testing" "testing"
"time" "time"
"git.vakhrushev.me/av/transcriber/internal/adapter/ffmpeg"
"git.vakhrushev.me/av/transcriber/internal/adapter/sqlite" "git.vakhrushev.me/av/transcriber/internal/adapter/sqlite"
"git.vakhrushev.me/av/transcriber/internal/entity" "git.vakhrushev.me/av/transcriber/internal/entity"
"git.vakhrushev.me/av/transcriber/internal/service" "git.vakhrushev.me/av/transcriber/internal/service"
@@ -56,7 +57,9 @@ func setupTestRouter(t *testing.T) (*gin.Engine, *TranscribeHandler) {
fileRepo := sqlite.NewFileRepository(db, gq) fileRepo := sqlite.NewFileRepository(db, gq)
jobRepo := sqlite.NewTranscriptJobRepository(db, gq) jobRepo := sqlite.NewTranscriptJobRepository(db, gq)
trsService := service.NewTranscribeService(jobRepo, fileRepo) converter := ffmpeg.NewFfmpegConverter()
trsService := service.NewTranscribeService(jobRepo, fileRepo, converter)
handler := NewTranscribeHandler(jobRepo, trsService) handler := NewTranscribeHandler(jobRepo, trsService)

View File

@@ -10,7 +10,6 @@ import (
"git.vakhrushev.me/av/transcriber/internal/contract" "git.vakhrushev.me/av/transcriber/internal/contract"
"git.vakhrushev.me/av/transcriber/internal/entity" "git.vakhrushev.me/av/transcriber/internal/entity"
"git.vakhrushev.me/av/transcriber/internal/repo/ffmpeg"
"git.vakhrushev.me/av/transcriber/internal/service/s3" "git.vakhrushev.me/av/transcriber/internal/service/s3"
"git.vakhrushev.me/av/transcriber/internal/service/speechkit" "git.vakhrushev.me/av/transcriber/internal/service/speechkit"
"github.com/google/uuid" "github.com/google/uuid"
@@ -19,12 +18,17 @@ import (
const baseStorageDir = "data/files" const baseStorageDir = "data/files"
type TranscribeService struct { type TranscribeService struct {
jobRepo contract.TranscriptJobRepository jobRepo contract.TranscriptJobRepository
fileRepo contract.FileRepository fileRepo contract.FileRepository
converter contract.AudioFileConverter
} }
func NewTranscribeService(jobRepo contract.TranscriptJobRepository, fileRepo contract.FileRepository) *TranscribeService { func NewTranscribeService(jobRepo contract.TranscriptJobRepository, fileRepo contract.FileRepository, converter contract.AudioFileConverter) *TranscribeService {
return &TranscribeService{jobRepo: jobRepo, fileRepo: fileRepo} return &TranscribeService{
jobRepo: jobRepo,
fileRepo: fileRepo,
converter: converter,
}
} }
func (s *TranscribeService) CreateTranscribeJob(file io.Reader, fileName string) (*entity.TranscribeJob, error) { func (s *TranscribeService) CreateTranscribeJob(file io.Reader, fileName string) (*entity.TranscribeJob, error) {
@@ -112,8 +116,7 @@ func (s *TranscribeService) FindAndRunConversionJob() error {
destFileName := fmt.Sprintf("%s%s", destFileId, ".ogg") destFileName := fmt.Sprintf("%s%s", destFileId, ".ogg")
destFilePath := filepath.Join(baseStorageDir, destFileName) destFilePath := filepath.Join(baseStorageDir, destFileName)
conv := ffmpeg.NewFileConverter() err = s.converter.Convert(srcFilePath, destFilePath)
err = conv.Convert(srcFilePath, destFilePath)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -12,6 +12,7 @@ import (
"syscall" "syscall"
"time" "time"
"git.vakhrushev.me/av/transcriber/internal/adapter/ffmpeg"
"git.vakhrushev.me/av/transcriber/internal/adapter/sqlite" "git.vakhrushev.me/av/transcriber/internal/adapter/sqlite"
httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http" httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http"
"git.vakhrushev.me/av/transcriber/internal/controller/worker" "git.vakhrushev.me/av/transcriber/internal/controller/worker"
@@ -55,7 +56,9 @@ func main() {
fileRepo := sqlite.NewFileRepository(db, gq) fileRepo := sqlite.NewFileRepository(db, gq)
jobRepo := sqlite.NewTranscriptJobRepository(db, gq) jobRepo := sqlite.NewTranscriptJobRepository(db, gq)
transcribeService := service.NewTranscribeService(jobRepo, fileRepo) converter := ffmpeg.NewFfmpegConverter()
transcribeService := service.NewTranscribeService(jobRepo, fileRepo, converter)
// Создаем воркеры // Создаем воркеры
conversionWorker := worker.NewConversionWorker(transcribeService) conversionWorker := worker.NewConversionWorker(transcribeService)