From 03106830e59252175984c2c88dc745f23d08dee5 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Tue, 12 Aug 2025 14:30:48 +0300 Subject: [PATCH] Move ffmpeg service to adapters --- .../ffmpeg/ffmpeg_converter.go} | 14 ++++++++------ internal/contract/contract.go | 2 +- internal/controller/http/transcribe_test.go | 5 ++++- internal/service/transcribe.go | 17 ++++++++++------- main.go | 5 ++++- 5 files changed, 27 insertions(+), 16 deletions(-) rename internal/{repo/ffmpeg/conv.go => adapter/ffmpeg/ffmpeg_converter.go} (79%) diff --git a/internal/repo/ffmpeg/conv.go b/internal/adapter/ffmpeg/ffmpeg_converter.go similarity index 79% rename from internal/repo/ffmpeg/conv.go rename to internal/adapter/ffmpeg/ffmpeg_converter.go index b24d40b..f1a4c24 100644 --- a/internal/repo/ffmpeg/conv.go +++ b/internal/adapter/ffmpeg/ffmpeg_converter.go @@ -6,26 +6,28 @@ import ( "os/exec" ) -type FileConverter struct { +const ffmpegExecutable = "ffmpeg" + +type FfmpegConverter struct { } -func NewFileConverter() *FileConverter { - return &FileConverter{} +func NewFfmpegConverter() *FfmpegConverter { + 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) { return fmt.Errorf("input file does not exist: %s", src) } // Проверяем, что 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) } // Создаем команду ffmpeg для конвертации в OGG - cmd := exec.Command("ffmpeg", + cmd := exec.Command(ffmpegExecutable, "-i", src, // входной файл "-c:a", "libvorbis", // кодек Vorbis для OGG "-q:a", "4", // качество аудио (0-10, где 4 - хорошее качество) diff --git a/internal/contract/contract.go b/internal/contract/contract.go index 847037e..cd68f2b 100644 --- a/internal/contract/contract.go +++ b/internal/contract/contract.go @@ -3,6 +3,6 @@ package contract type ObjectStorage interface { } -type FileConverter interface { +type AudioFileConverter interface { Convert(src, dest string) error } diff --git a/internal/controller/http/transcribe_test.go b/internal/controller/http/transcribe_test.go index aeb3d9f..547852a 100644 --- a/internal/controller/http/transcribe_test.go +++ b/internal/controller/http/transcribe_test.go @@ -15,6 +15,7 @@ import ( "testing" "time" + "git.vakhrushev.me/av/transcriber/internal/adapter/ffmpeg" "git.vakhrushev.me/av/transcriber/internal/adapter/sqlite" "git.vakhrushev.me/av/transcriber/internal/entity" "git.vakhrushev.me/av/transcriber/internal/service" @@ -56,7 +57,9 @@ func setupTestRouter(t *testing.T) (*gin.Engine, *TranscribeHandler) { fileRepo := sqlite.NewFileRepository(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) diff --git a/internal/service/transcribe.go b/internal/service/transcribe.go index 06d6e3d..356618a 100644 --- a/internal/service/transcribe.go +++ b/internal/service/transcribe.go @@ -10,7 +10,6 @@ import ( "git.vakhrushev.me/av/transcriber/internal/contract" "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/speechkit" "github.com/google/uuid" @@ -19,12 +18,17 @@ import ( const baseStorageDir = "data/files" type TranscribeService struct { - jobRepo contract.TranscriptJobRepository - fileRepo contract.FileRepository + jobRepo contract.TranscriptJobRepository + fileRepo contract.FileRepository + converter contract.AudioFileConverter } -func NewTranscribeService(jobRepo contract.TranscriptJobRepository, fileRepo contract.FileRepository) *TranscribeService { - return &TranscribeService{jobRepo: jobRepo, fileRepo: fileRepo} +func NewTranscribeService(jobRepo contract.TranscriptJobRepository, fileRepo contract.FileRepository, converter contract.AudioFileConverter) *TranscribeService { + return &TranscribeService{ + jobRepo: jobRepo, + fileRepo: fileRepo, + converter: converter, + } } 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") destFilePath := filepath.Join(baseStorageDir, destFileName) - conv := ffmpeg.NewFileConverter() - err = conv.Convert(srcFilePath, destFilePath) + err = s.converter.Convert(srcFilePath, destFilePath) if err != nil { return err } diff --git a/main.go b/main.go index 24f0662..c129913 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "syscall" "time" + "git.vakhrushev.me/av/transcriber/internal/adapter/ffmpeg" "git.vakhrushev.me/av/transcriber/internal/adapter/sqlite" httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http" "git.vakhrushev.me/av/transcriber/internal/controller/worker" @@ -55,7 +56,9 @@ func main() { fileRepo := sqlite.NewFileRepository(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)