diff --git a/src/Protocol/FileSystem.php b/src/Protocol/FileSystem.php new file mode 100644 index 0000000..0010759 --- /dev/null +++ b/src/Protocol/FileSystem.php @@ -0,0 +1,103 @@ + + * + * @license http://opensource.org/licenses/MIT MIT + * @copyright Copyright (c) 2017-2018 Dmitry Arhitector + */ +namespace Arhitector\Transcoder\Protocol; + +use Arhitector\Transcoder\Exception\TranscoderException; +use InvalidArgumentException; + +/** + * Class FileSystem + * + * @package Arhitector\Transcoder\Protocol + */ +class FileSystem implements ProtocolInterface +{ + /** + * @var string The full path to the file. + */ + protected $filePath; + + /** + * FileSystem constructor. + * + * @param string $filePath + */ + public function __construct($filePath) + { + $this->setFilePath($filePath); + } + + /** + * Get the full path to the file. + * + * @return string + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * Set file path. + * + * @param string $filePath + * + * @return FileSystem + * @throws InvalidArgumentException + * @throws TranscoderException + */ + protected function setFilePath($filePath) + { + if ( ! is_string($filePath)) + { + throw new InvalidArgumentException('File path must be a string type.'); + } + + if (preg_match('~^(\w+:)?//~', $filePath) || is_link($filePath)) + { + throw new InvalidArgumentException('File path must be a local path.'); + } + + $filePath = realpath($filePath); + + if ( ! is_file($filePath)) + { + throw new TranscoderException('File path not found.'); + } + + $this->filePath = $filePath; + + return $this; + } + + /** + * Retrieve an external iterator + * + * @link https://php.net/manual/en/iteratoraggregate.getiterator.php + * @return \Traversable An instance of an object implementing Iterator or Traversable + */ + public function getIterator() + { + $handle = fopen($this->getFilePath(), 'rb'); + + while ( ! feof($handle)) + { + yield fread($handle, 2097152); + } + + fclose($handle); + + return ; + } + +} \ No newline at end of file diff --git a/src/Protocol/ProtocolInterface.php b/src/Protocol/ProtocolInterface.php new file mode 100644 index 0000000..52b4d64 --- /dev/null +++ b/src/Protocol/ProtocolInterface.php @@ -0,0 +1,23 @@ + + * + * @license http://opensource.org/licenses/MIT MIT + * @copyright Copyright (c) 2017-2018 Dmitry Arhitector + */ +namespace Arhitector\Transcoder\Protocol; + +/** + * Interface ProtocolInterface + * + * @package Arhitector\Transcoder\Protocol + */ +interface ProtocolInterface extends \IteratorAggregate +{ + +} \ No newline at end of file diff --git a/src/Service/Decoder.php b/src/Service/Decoder.php index 562949f..e6315da 100644 --- a/src/Service/Decoder.php +++ b/src/Service/Decoder.php @@ -81,9 +81,10 @@ public function demuxing(TranscodeInterface $media) '-show_streams', '-show_error', '-i', - $media->getFilePath() + '-' ])) ->setPrefix($this->options['ffprobe.path']) + ->setInput($media->getSource()) ->getProcess() ->mustRun() ->getOutput(); diff --git a/src/Service/Encoder.php b/src/Service/Encoder.php index 1008382..7ebb8f5 100644 --- a/src/Service/Encoder.php +++ b/src/Service/Encoder.php @@ -151,7 +151,7 @@ public function transcoding(TranscodeInterface $media, FormatInterface $format, $reflection = new \ReflectionProperty($localMedia, 'filters'); $reflection->setAccessible(true); - $localHeap = new Heap(['input' => $localMedia->getFilePath()]); + $localHeap = new Heap(['input' => '-'/*$localMedia->getFilePath()*/]); /** @var FilterInterface $filter */ foreach (clone $reflection->getValue($localMedia) as $filter) @@ -223,6 +223,7 @@ public function transcoding(TranscodeInterface $media, FormatInterface $format, $process = (new ProcessBuilder($_options)) ->setPrefix($this->options['ffmpeg.path']) ->setTimeout($this->options['timeout']) + ->setInput($media->getSource()) ->getProcess(); $format->emit('before.pass', $media, $format, $process); diff --git a/src/Stream/StreamTrait.php b/src/Stream/StreamTrait.php index 42cef0c..c2aa8d2 100644 --- a/src/Stream/StreamTrait.php +++ b/src/Stream/StreamTrait.php @@ -15,6 +15,7 @@ use Arhitector\Transcoder\Codec; use Arhitector\Transcoder\Filter\SimpleFilter; use Arhitector\Transcoder\Format\FormatInterface; +use Arhitector\Transcoder\Protocol\ProtocolInterface; use Arhitector\Transcoder\TimeInterval; use Arhitector\Transcoder\Traits\FilePathAwareTrait; use Arhitector\Transcoder\Traits\MetadataTrait; @@ -105,6 +106,11 @@ public static function create(TranscodeInterface $media, array $options = []) */ protected $media; + /** + * @var ProtocolInterface + */ + protected $source; + /** * Stream constructor. * @@ -115,7 +121,7 @@ public static function create(TranscodeInterface $media, array $options = []) */ private function __construct(TranscodeInterface $media) { - $this->setFilePath($media->getFilePath()); + $this->setSource($media->getSource()); $this->media = $media; } @@ -213,6 +219,25 @@ public function getDuration() return $this->duration; } + /** + * @return ProtocolInterface + */ + public function getSource() + { + return $this->source; + } + + /** + * @param ProtocolInterface $source + * @return StreamTrait + */ + public function setSource($source) + { + $this->source = $source; + + return $this; + } + /** * Stream save. * diff --git a/src/TranscodeTrait.php b/src/TranscodeTrait.php index 51bf775..8edca67 100644 --- a/src/TranscodeTrait.php +++ b/src/TranscodeTrait.php @@ -8,7 +8,7 @@ * @author Dmitry Arhitector * * @license http://opensource.org/licenses/MIT MIT - * @copyright Copyright (c) 2017 Dmitry Arhitector + * @copyright Copyright (c) 2017-2018 Dmitry Arhitector */ namespace Arhitector\Transcoder; @@ -17,6 +17,8 @@ use Arhitector\Transcoder\Exception\TranscoderException; use Arhitector\Transcoder\Filter\Graph; use Arhitector\Transcoder\Format\FormatInterface; +use Arhitector\Transcoder\Protocol\FileSystem; +use Arhitector\Transcoder\Protocol\ProtocolInterface; use Arhitector\Transcoder\Service\ServiceFactory; use Arhitector\Transcoder\Service\ServiceFactoryInterface; use Arhitector\Transcoder\Stream\AudioStream; @@ -59,18 +61,23 @@ trait TranscodeTrait */ protected $filters; + /** + * @var ProtocolInterface + */ + protected $source; + /** * The constructor. * - * @param string $filePath - * @param ServiceFactoryInterface $service + * @param ProtocolInterface|string $source + * @param ServiceFactoryInterface $service * * @throws \Arhitector\Transcoder\Exception\TranscoderException * @throws \InvalidArgumentException */ - public function __construct($filePath, ServiceFactoryInterface $service = null) + public function __construct($source, ServiceFactoryInterface $service = null) { - $this->setFilePath($filePath); + $this->setSource($source instanceof ProtocolInterface ? $source : new FileSystem($source)); $this->setServiceFactory($service ?: new ServiceFactory()); /** @noinspection ExceptionsAnnotatingAndHandlingInspection */ @@ -85,6 +92,16 @@ public function __construct($filePath, ServiceFactoryInterface $service = null) $this->initialize($demuxing); } + /** + * Returns the current source. + * + * @return ProtocolInterface + */ + public function getSource() + { + return $this->source; + } + /** * Get current format. * @@ -254,7 +271,25 @@ protected function setServiceFactory(ServiceFactoryInterface $service) */ protected function getMimeType() { - return mime_content_type($this->getFilePath()); + if ($this->getSource() instanceof FileSystem) + { + return mime_content_type($this->getSource()->getFilePath()); + } + + return ''; + } + + /** + * + * @param ProtocolInterface $source + * + * @return $this + */ + protected function setSource(ProtocolInterface $source) + { + $this->source = $source; + + return $this; } /**