Просмотр файла vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Filters/Video/ExtractMultipleFramesFilter.php

Размер файла: 4.29Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of PHP-FFmpeg.
  5. *
  6. * (c) Strime <romain@strime.io>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace FFMpeg\Filters\Video;
  13.  
  14. use FFMpeg\Exception\InvalidArgumentException;
  15. use FFMpeg\Exception\RuntimeException;
  16. use FFMpeg\Media\Video;
  17. use FFMpeg\Format\VideoInterface;
  18.  
  19. class ExtractMultipleFramesFilter implements VideoFilterInterface
  20. {
  21. /** will extract a frame every second */
  22. const FRAMERATE_EVERY_SEC = '1/1';
  23. /** will extract a frame every 2 seconds */
  24. const FRAMERATE_EVERY_2SEC = '1/2';
  25. /** will extract a frame every 5 seconds */
  26. const FRAMERATE_EVERY_5SEC = '1/5';
  27. /** will extract a frame every 10 seconds */
  28. const FRAMERATE_EVERY_10SEC = '1/10';
  29. /** will extract a frame every 30 seconds */
  30. const FRAMERATE_EVERY_30SEC = '1/30';
  31. /** will extract a frame every minute */
  32. const FRAMERATE_EVERY_60SEC = '1/60';
  33.  
  34. /** @var integer */
  35. private $priority;
  36. private $frameRate;
  37. private $destinationFolder;
  38. private $frameFileType = 'jpg';
  39.  
  40. /** @var array */
  41. private static $supportedFrameFileTypes = ['jpg', 'jpeg', 'png'];
  42.  
  43. public function __construct($frameRate = self::FRAMERATE_EVERY_SEC, $destinationFolder = __DIR__, $priority = 0)
  44. {
  45. $this->priority = $priority;
  46. $this->frameRate = $frameRate;
  47.  
  48. // Make sure that the destination folder has a trailing slash
  49. if(strcmp( substr($destinationFolder, -1), "/") != 0)
  50. $destinationFolder .= "/";
  51.  
  52. // Set the destination folder
  53. $this->destinationFolder = $destinationFolder;
  54. }
  55.  
  56. /**
  57. * @param string $frameFileType
  58. * @throws \FFMpeg\Exception\InvalidArgumentException
  59. * @return ExtractMultipleFramesFilter
  60. */
  61. public function setFrameFileType($frameFileType) {
  62. if (in_array($frameFileType, self::$supportedFrameFileTypes)) {
  63. $this->frameFileType = $frameFileType;
  64. return $this;
  65. }
  66.  
  67. throw new InvalidArgumentException('Invalid frame file type, use: ' . implode(',', self::$supportedFrameFileTypes));
  68. }
  69.  
  70. /**
  71. * {@inheritdoc}
  72. */
  73. public function getPriority()
  74. {
  75. return $this->priority;
  76. }
  77.  
  78. /**
  79. * {@inheritdoc}
  80. */
  81. public function getFrameRate()
  82. {
  83. return $this->frameRate;
  84. }
  85.  
  86. /**
  87. * {@inheritdoc}
  88. */
  89. public function getDestinationFolder()
  90. {
  91. return $this->destinationFolder;
  92. }
  93.  
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function apply(Video $video, VideoInterface $format)
  98. {
  99. $commands = array();
  100. $duration = 0;
  101.  
  102. try {
  103. // Get the duration of the video
  104. foreach ($video->getStreams()->videos() as $stream) {
  105. if ($stream->has('duration')) {
  106. $duration = $stream->get('duration');
  107. }
  108. }
  109.  
  110. // Get the number of frames per second we have to extract.
  111. if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $this->frameRate, $matches) !== FALSE){
  112. $operator = $matches[2];
  113.  
  114. switch($operator){
  115. case '/':
  116. $nbFramesPerSecond = $matches[1] / $matches[3];
  117. break;
  118.  
  119. default:
  120. throw new InvalidArgumentException('The frame rate is not a proper division: ' . $this->frameRate);
  121. break;
  122. }
  123. }
  124.  
  125. // Set the number of digits to use in the exported filenames
  126. $nbImages = ceil( $duration * $nbFramesPerSecond );
  127.  
  128. if($nbImages < 100)
  129. $nbDigitsInFileNames = "02";
  130. elseif($nbImages < 1000)
  131. $nbDigitsInFileNames = "03";
  132. else
  133. $nbDigitsInFileNames = "06";
  134.  
  135. // Set the parameters
  136. $commands[] = '-vf';
  137. $commands[] = 'fps=' . $this->frameRate;
  138. $commands[] = $this->destinationFolder . 'frame-%'.$nbDigitsInFileNames.'d.' . $this->frameFileType;
  139. }
  140. catch (RuntimeException $e) {
  141. throw new RuntimeException('An error occured while extracting the frames: ' . $e->getMessage() . '. The code: ' . $e->getCode());
  142. }
  143.  
  144. return $commands;
  145. }
  146. }