diff --git a/composer.json b/composer.json index b0ea1e1e..c42c653d 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ ], "require": { "php": "^8.1 || ^8.2 || ^8.3", - "bamarni/composer-bin-plugin": "^1.8" + "bamarni/composer-bin-plugin": "^1.8", + "php-ffmpeg/php-ffmpeg": "^1.1" }, "scripts": { "lint": "find . -name \\*.php -not -path './vendor*' -print0 | xargs -0 -n1 php -l", diff --git a/lib/Service/OpenAiAPIService.php b/lib/Service/OpenAiAPIService.php index 50e1fd2f..e29b94b5 100644 --- a/lib/Service/OpenAiAPIService.php +++ b/lib/Service/OpenAiAPIService.php @@ -28,6 +28,8 @@ use OCP\TaskProcessing\ShapeEnumValue; use Psr\Log\LoggerInterface; use RuntimeException; +use FFMpeg\FFMpeg; +use FFMpeg\Format\Audio\Opus; /** * Service to make requests to OpenAI/LocalAI REST API @@ -602,13 +604,42 @@ public function transcribeFile( bool $translate = false, string $model = Application::DEFAULT_MODEL_ID, ): string { + + $inputFilePath = '/mnt/ncdata' . $file->getPath(); + $tempFilePath = preg_replace('/\.webm$/', '.ogg', $inputFilePath); + + if (str_ends_with($file->getName(), '.webm')) { + try { + $ffmpeg = FFMpeg::create(); + $audio = $ffmpeg->open($inputFilePath); + + $format = new Opus(); + $format->setAudioChannels(1) + ->setAudioKiloBitrate(12) + ->setApplication('voip'); + + $audio->save($format, $tempFilePath); + + $fileContent = file_get_contents($tempFilePath); + } catch (\Exception $e) { + $this->logger->error('FFmpeg encoding failed for file: ' . $inputFilePath . '. Error: ' . $e->getMessage()); + throw new Exception($this->l10n->t('Could not encode audio file.'), Http::STATUS_INTERNAL_SERVER_ERROR); + } + } else { + $fileContent = $file->getContent(); + } + try { - $transcriptionResponse = $this->transcribe($userId, $file->getContent(), $translate, $model); + $transcriptionResponse = $this->transcribe($userId, $fileContent, $translate, $model); } catch (NotPermittedException|LockedException|GenericFileException $e) { $this->logger->warning('Could not read audio file: ' . $file->getPath() . '. Error: ' . $e->getMessage(), ['app' => Application::APP_ID]); throw new Exception($this->l10n->t('Could not read audio file.'), Http::STATUS_INTERNAL_SERVER_ERROR); } - + + if (file_exists($tempFilePath)) { + unlink($tempFilePath); + } + return $transcriptionResponse; }