elevenlabs_field-1.0.0-beta7/src/ElevenLabsGenerateService.php

src/ElevenLabsGenerateService.php
<?php

namespace Drupal\elevenlabs_field;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Utility\Token;
use Drupal\file\FileRepositoryInterface;

/**
 * Takes care of the Generating files from ElevenLabs.
 */
class ElevenLabsGenerateService {

  /**
   * The file system interface.
   */
  protected FileSystemInterface $fileSystem;

  /**
   * The api interface.
   */
  protected ElevenLabsApiService $api;

  /**
   * The entity type manager.
   */
  protected EntityTypeManagerInterface $entityType;

  /**
   * The file repository.
   */
  protected FileRepositoryInterface $fileRepo;

  /**
   * The token system.
   */
  protected Token $token;

  /**
   * The models.
   */
  protected array $models = [];

  /**
   * Construtor of ElevenLabs Generator Service.
   *
   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
   *   The file system interface.
   * @param \Drupal\elevenlabs_field\ElevenLabsApiService $api
   *   The ElevenLabs API interface.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityType
   *   The Entity Type manager interface.
   * @param \Drupal\file\FileRepositoryInterface $fileRepo
   *   The file repository.
   * @param \Drupal\Core\Utility\Token $token
   *   The token service.
   */
  public function __construct(FileSystemInterface $fileSystem, ElevenLabsApiService $api, EntityTypeManagerInterface $entityType, FileRepositoryInterface $fileRepo, Token $token) {
    $this->fileSystem = $fileSystem;
    $this->api = $api;
    $this->entityType = $entityType;
    $this->fileRepo = $fileRepo;
    $this->models = $this->api->getModels();
    $this->token = $token;
  }

  /**
   * Generate files.
   *
   * @param string $text
   *   The text to create for.
   * @param string $speaker
   *   The speaker to create for.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $fieldDefinition
   *   The field definition.
   * @param string $model
   *   The model to create with.
   * @param array $options
   *   The extra options.
   *
   * @return array
   *   An array of file and history id.
   */
  public function generateFile($text, $speaker, FieldDefinitionInterface $fieldDefinition, $model, $options = []) {
    $return = [];
    $filePath = $this->getFilePath($fieldDefinition);

    $audioData = $this->api->textToSpeech($text, $speaker, $model, $options);

    if (is_string($audioData)) {
      // Remove old data if exists.
      $file = $this->generateAudio($audioData, $filePath);
      // Elevenlabs is not consistent with writes.
      sleep(1);
      $historyId = $this->findHistoryId($text, $speaker);
      if ($historyId && $file) {
        $return = [
          'file' => $file,
          'history_item_id' => $historyId,
        ];
      }
    }
    return $return;
  }

  /**
   * Gets the file path.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $fieldDefinition
   *   The field definition interface.
   *
   * @return string
   *   The path.
   */
  public function getFilePath(FieldDefinitionInterface $fieldDefinition) {
    $settings = $fieldDefinition->getSettings();
    $path = $settings['uri_scheme'] ?? 'public';
    $path .= '://' . rtrim($this->token->replace($settings['file_directory']), '/');
    $path .= '/' . $this->token->replace($settings['file_name'] ?? 'elevenlabs') . '.mp3';

    return $path;
  }

  /**
   * Get the wanted model.
   *
   * @param string $modelName
   *   The model or auto.
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity.
   *
   * @return string
   *   The model.
   */
  public function validateModel($modelName, ContentEntityInterface $entity) {
    // Only change if model is auto.
    if ($modelName == 'auto') {
      $modelName = ElevenLabsApiService::$defaultModel;
      $langCode = $entity->get('langcode')->value ?? NULL;
      if ($langCode) {
        foreach ($this->models as $model) {
          if (array_search($langCode, array_column($model['languages'], 'language_id'), TRUE)) {
            return $model['model_id'];
          }
        }
      }
    }
    return $modelName;
  }

  /**
   * Remove old file.
   *
   * @param int $id
   *   The file to remove.
   */
  public function removeFile($id) {
    if ($id) {
      $file = $this->entityType->getStorage('file')->load($id);
      $file ? $file->delete() : NULL;
    }
  }

  /**
   * Generate Audio file.
   *
   * @param string $audioData
   *   Binary.
   * @param string $filePath
   *   Path to store.
   *
   * @return \Drupal\file\Entity\File
   *   A file entity.
   */
  private function generateAudio($audioData, $filePath) {
    $dir = substr($filePath, 0, -(strlen(basename($filePath))));
    $this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
    $file = $this->fileRepo->writeData($audioData, $filePath, FileSystemInterface::EXISTS_RENAME);
    return $file;
  }

  /**
   * Find the history Id.
   *
   * @param string $text
   *   The text to search for.
   * @param string $speaker
   *   The speaker to search for.
   *
   * @return string
   *   The history item id.
   */
  private function findHistoryId($text, $speaker) {
    $history = $this->api->getHistoryListing();
    if (is_array($history)) {
      foreach ($history['history'] as $historyItem) {
        if ($historyItem['text'] == $text && $historyItem['voice_id'] == $speaker) {
          return $historyItem['history_item_id'];
        }
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc