more_fields-2.2.19/modules/video/src/Services/MoreFieldsVideoConverter.php

modules/video/src/Services/MoreFieldsVideoConverter.php
<?php

namespace Drupal\more_fields_video\Services;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use FFMpeg\FFMpeg;
use FFMpeg\Format\Video\WebM;
use FFMpeg\Format\Video\X264;
use FFMpeg\Format\Video\Ogg;
use FFMpeg\Exception\ExecutableNotFoundException;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\file\Entity\File;
use FFMpeg\Coordinate\TimeCode;
use Drupal\more_fields_video\Entity\MultiformatVideo;
use Drupal\Core\File\FileSystem;

/**
 * Prepares the salutation to the world.
 */
class MoreFieldsVideoConverter {
  
  use StringTranslationTrait;
  protected $thumb_extension = '.png';
  protected $thumb_mime = 'image/png';
  
  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;
  /**
   *
   * @var \Drupal\Core\File\FileSystem
   */
  protected $FileSystem;
  
  /**
   * Constructs a new MyCustomService object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *        The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, FileSystem $FileSystem) {
    $this->entityTypeManager = $entity_type_manager;
    $this->FileSystem = $FileSystem;
  }
  
  /**
   * Permet de generer la miniature à partir de la video.
   *
   * @param File $file
   * @param EntityStorageInterface $multiformatHandler
   * @return MultiformatVideo|NULL
   */
  public function getMultiFormat($file, $multiformatHandler = null) {
    $multiformat = null;
    $fileType = explode("/", $file->getMimeType())[0];
    
    if ($fileType === "video") {
      if (!isset($multiformatHandler)) {
        $multiformatHandler = $this->entityTypeManager->getStorage("multiformat_video");
      }
      /**
       *
       * @param MultiformatVideo|null $multiformat
       */
      $multiformat = $multiformatHandler->load($file->id());
      
      if (!$multiformat) {
        $result = $this->createThumbFile($file);
        if ($result !== FALSE) {
          $multiformat = $this->sync_multiformat($file->id(), $result, $multiformatHandler);
        }
      }
    }
    return $multiformat;
  }
  
  /**
   * Cette fonction vise à convertir les videos mov et quictime en webm.
   *
   * @param int $fid
   * @param EntityStorageInterface $multiformatHandler
   * @return MultiformatVideo|NULL
   */
  public function manageUploadedFile($fid, $multiformatHandler = null, $generateThumb = True, $convertVideo = True, $vFormat = "webm", $toConvert = [
    "mov",
    "quicktime"
  ]) {
    $multiformat = null;
    $file = File::load($fid);
    try {
      if ($convertVideo) {
        $multiformat = null;
        $fileMime = explode("/", $file->getMimeType());
        if ($fileMime[0] === "video") {
          if ($fileMime[1] != $vFormat && in_array($fileMime[1], $toConvert)) {
            $convertedFilePath = $this->convertVideo($file, [
              $vFormat
            ]);
            $file->setFileUri($convertedFilePath[$vFormat]['uri']);
            $file->setFilename(pathinfo($convertedFilePath[$vFormat]['uri'], PATHINFO_FILENAME) . '.' . $vFormat);
            $file->save();
          }
        }
      }
      if ($generateThumb) {
        $multiformat = $this->getMultiFormat($file, $multiformatHandler);
      }
    }
    catch (ExecutableNotFoundException $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
    }
    catch (\Error $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
    }
    return [
      "multiformat" => $multiformat,
      "furi" => $file->getFileUri()
    ];
  }
  
  /**
   * Permet de convertir les videos en un formet bien definit.
   */
  public function ConvertVideoToRightFormat(File $file, array $outputFormat, $updateFile = false) {
    try {
      $files = [];
      $fileMime = explode("/", $file->getMimeType());
      $files[$file->id()] = $file;
      if ($fileMime[0] === "video" && $outputFormat) {
        $extention = $fileMime[1];
        if ($extention == 'mp4' && $this->isMp4H264($file)) {
          $index = array_search("mp4", $outputFormat);
          if ($index !== false) {
            unset($outputFormat[$index]);
          }
        }
        elseif ($extention == 'ogg') {
          $index = array_search("ogg", $outputFormat);
          if ($index !== false) {
            unset($outputFormat[$index]);
          }
        }
        elseif ($extention == 'webm') {
          $index = array_search("webm", $outputFormat);
          
          if ($index !== false) {
            unset($outputFormat[$index]);
          }
        }
        if ($outputFormat) {
          $convertedFilePath = $this->convertVideo($file, $outputFormat);
          $uid = \Drupal::currentUser()->id();
          // Pour l'instant, nous avons un soucis pour ajouter les nouveaux
          // elements aux contenus encours.
          foreach ($convertedFilePath as $format => $data) {
            if ($updateFile)
              $newFile = $file;
            else
              $newFile = $file->createDuplicate();
            $newFile->setFileUri($data['uri']);
            $newFile->setFilename(pathinfo($data['filename'], PATHINFO_FILENAME) . '.' . $format);
            $newFile->setMimeType("video/$format");
            $newFile->setOwnerId($uid);
            $newFile->save();
            $files[$newFile->id()] = $newFile;
          }
        }
        return $files;
      }
      return $files;
    }
    catch (ExecutableNotFoundException $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
    }
    catch (\Error $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
    }
  }
  
  /**
   *
   * @param File $file
   * @return boolean
   */
  function isMp4H264(File $file) {
    $filePath = $this->FileSystem->realpath($file->getFileUri());
    // Commande pour obtenir les informations du fichier vidéo
    $command = "ffmpeg -i " . escapeshellarg($filePath) . " 2>&1";
    $output = shell_exec($command);
    
    // Vérification du format et du codec
    $isMp4 = strpos($output, 'Video: h264') !== false;
    $isH264 = strpos($output, 'mp4') !== false;
    if ($isH264) {
      \Drupal::messenger()->addStatus("Le format video mp4 est H264");
    }
    else
      \Drupal::messenger()->addWarning("Le format video mp4 n'est pas H264");
    return $isMp4 && $isH264;
  }
  
  /**
   * Cette methode est statique car elle est utilisé par à l'exterieur de la
   * classe.
   * la transférer dans un service est une option
   *
   * @param File $thumb_file
   * @return MultiformatVideo
   */
  public function sync_multiformat($video_id, File $thumb_file, EntityStorageInterface &$multiformatHandler) {
    // creating and handling the multiformat
    /**
     *
     * @var MultiformatVideo $multiformat
     */
    $multiformat = $multiformatHandler->load($video_id) ?? $multiformatHandler->create();
    $thumb_file->setPermanent();
    $thumb_file->save();
    $multiformat->setThumbId($thumb_file->id());
    $multiformat->setVideoId($video_id);
    $multiformat->save();
    return $multiformat;
  }
  
  /**
   * create the thumb file for a video in a given format (the default format is
   * png)
   *
   * @param int $video_id
   *        Id of the seed Drupal\file\Entity\File (video) to be converted
   * @param int $frame_second
   *        the second where the frame will be captured
   * @return File|boolean the not saved file that have been generated or false
   */
  protected function createThumbFile(File $file, $frame_seconde = 1) {
    $file_uri = $file->getFileUri();
    [
      'filename' => $filename,
      'dirname' => $dirname
    ] = pathinfo($file_uri);
    try {
      // create thumb path + name
      $thumb_path = $dirname . '/' . $filename . $this->thumb_extension;
      $ffmpeg = FFMpeg::create();
      $ffm_video = $ffmpeg->open($this->FileSystem->realpath($file_uri));
      $ffm_video->frame(TimeCode::fromSeconds($frame_seconde))->save($this->FileSystem->realpath($thumb_path));
      /**
       *
       * @var File $thumb_file
       */
      $thumb_file = File::create();
      $thumb_file->setFileUri($thumb_path);
      $thumb_file->setFilename(pathinfo($thumb_path, PATHINFO_FILENAME));
      $thumb_file->setMimeType($this->thumb_mime);
      return $thumb_file;
    }
    catch (\Error $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
      return FALSE;
    }
  }
  
  /**
   *
   * @param File $file
   * @return string path of the new file
   */
  protected function convertVideo(File $file, array $finalTypes) {
    $file_uri = $file->getFileUri();
    [
      'filename' => $filename,
      'dirname' => $dirname
    ] = pathinfo($file_uri);
    $convertedVidPath = [];
    $ffmpeg = FFMpeg::create();
    
    $ffm_video = $ffmpeg->open($this->FileSystem->realpath($file_uri));
    try {
      \Drupal::messenger()->addStatus("Video converti");
      foreach ($finalTypes as $extention) {
        $PathUri = $dirname . '/' . $filename . "." . $extention;
        $newpath = $this->FileSystem->realpath($PathUri);
        switch ($extention) {
          case 'webm':
            $ffm_video->save(new WebM(), $newpath);
            $convertedVidPath[$extention] = [];
            $convertedVidPath[$extention]['uri'] = $PathUri;
            $convertedVidPath[$extention]['filename'] = $filename . "." . $extention;
            // $convertedVidPath[$extention]['size'] = filesize($realpath);
            break;
          case 'mp4':
            $ffm_video->save(new X264(), $newpath);
            $convertedVidPath[$extention] = [];
            $convertedVidPath[$extention]['uri'] = $PathUri;
            $convertedVidPath[$extention]['filename'] = $filename . "." . $extention;
            // $convertedVidPath[$extention]['size'] = filesize($realpath);
            break;
          case 'ogg':
            $ffm_video->save(new Ogg(), $newpath);
            $convertedVidPath[$extention] = [];
            $convertedVidPath[$extention]['uri'] = $PathUri;
            $convertedVidPath[$extention]['filename'] = $filename . "." . $extention;
            // $convertedVidPath[$extention]['size'] = filesize($realpath);
            break;
        }
      }
      return $convertedVidPath;
    }
    catch (ExecutableNotFoundException $e) {
      \Drupal::logger('more_fields_video')->error($e->getMessage());
    }
    catch (\Throwable $th) {
      \Drupal::logger('more_fields_video')->error($th->getMessage());
      return FALSE;
    }
  }
  
  /**
   * define in the extension of the thumb when it will be genereted
   * at the same time it define the thumb mime
   *
   * @param string $extension
   *        extension of the thumb. ex: png, jpeg, webp(not supported yet)
   */
  public function setThumbExtension($extension) {
    $this->thumb_extension = "." . $extension;
    $this->thumb_mime = "image/" . $extension;
  }
}

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

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