From ac0e9dfd4173c7defe671fea237ad08a4e0dfd5e Mon Sep 17 00:00:00 2001 From: Amin Date: Fri, 6 Mar 2020 18:13:20 +0330 Subject: [PATCH] bug fixes #33 and other minor improvements --- src/DASH.php | 4 +- src/Filters/DASHFilter.php | 74 ++++++++++--------- src/Filters/HLSFilter.php | 11 +-- src/Filters/{Filter.php => StreamFilter.php} | 13 ++-- ...nterface.php => StreamFilterInterface.php} | 14 +++- src/Filters/StreamToFileFilter.php | 16 +--- src/HLS.php | 5 +- src/Metadata.php | 58 +++++++-------- src/{Export.php => Stream.php} | 17 ++--- src/StreamInterface.php | 40 ++++++++++ src/StreamToFile.php | 7 +- src/Streaming.php | 8 +- tests/DASHFiltersTest.php | 4 +- tests/DASHTest.php | 6 +- tests/HLSFiltersTest.php | 4 +- tests/HLSTest.php | 4 +- 16 files changed, 162 insertions(+), 123 deletions(-) rename src/Filters/{Filter.php => StreamFilter.php} (73%) rename src/Filters/{FilterStreamingInterface.php => StreamFilterInterface.php} (52%) rename src/{Export.php => Stream.php} (93%) create mode 100644 src/StreamInterface.php diff --git a/src/DASH.php b/src/DASH.php index 12fd2fa..d77afcd 100644 --- a/src/DASH.php +++ b/src/DASH.php @@ -12,7 +12,7 @@ namespace Streaming; use Streaming\Filters\DASHFilter; -use Streaming\Filters\FilterStreamingInterface; +use Streaming\Filters\StreamFilterInterface; class DASH extends Streaming { @@ -82,7 +82,7 @@ public function isGenerateHlsPlaylist(): bool /** * @return DASHFilter */ - protected function getFilter(): FilterStreamingInterface + protected function getFilter(): StreamFilterInterface { return new DASHFilter($this); } diff --git a/src/Filters/DASHFilter.php b/src/Filters/DASHFilter.php index c810b92..46346ac 100644 --- a/src/Filters/DASHFilter.php +++ b/src/Filters/DASHFilter.php @@ -13,62 +13,62 @@ namespace Streaming\Filters; -use Streaming\DASH; +use Streaming\StreamInterface; use Streaming\Format\X264; use Streaming\Representation; -class DASHFilter extends Filter +class DASHFilter extends StreamFilter { + /** @var \Streaming\DASH */ + private $dash; /** - * @param $media + * @param StreamInterface $stream */ - public function setFilter($media): void + public function streamFilter(StreamInterface $stream): void { - $this->filter = $this->DASHFilter($media); + $this->dash = $stream; + $this->set(); } /** - * @param DASH $dash * @return array */ - private function DASHFilter(DASH $dash): array + private function set() { - $filter = $this->getBaseFilters($dash, count($dash->getRepresentations())); + $this->filter = $this->getBaseFilters(); - foreach ($dash->getRepresentations() as $key => $representation) { - $filter[] = "-map"; - $filter[] = "0"; - $filter[] = "-b:v:" . $key; - $filter[] = $representation->getKiloBitrate() . "k"; - $filter = array_merge($filter, $this->getAudioBitrate($representation, $key)); + foreach ($this->dash->getRepresentations() as $key => $representation) { + $this->filter[] = "-map"; + $this->filter[] = "0"; + $this->filter[] = "-b:v:" . $key; + $this->filter[] = $representation->getKiloBitrate() . "k"; + $this->filter = array_merge($this->filter, $this->getAudioBitrate($representation, $key)); if (null !== $representation->getResize()) { - $filter[] = "-s:v:" . $key; - $filter[] = $representation->getResize(); + $this->filter[] = "-s:v:" . $key; + $this->filter[] = $representation->getResize(); } } - if ($dash->getAdaption()) { - $filter[] = "-adaptation_sets"; - $filter[] = $dash->getAdaption(); + if ($this->dash->getAdaption()) { + $this->filter[] = "-adaptation_sets"; + $this->filter[] = $this->dash->getAdaption(); } - $filter = array_merge($filter, $dash->getAdditionalParams()); - $filter = array_merge($filter, ["-strict", $dash->getStrict()]); + $this->filter = array_merge($this->filter, $this->dash->getAdditionalParams()); + $this->filter = array_merge($this->filter, ["-strict", $this->dash->getStrict()]); - return $filter; + return $this->filter; } /** - * @param $dash - * @param $count + * @return array */ - private function getBaseFilters(DASH $dash, int $count): array + private function getBaseFilters(): array { - $dirname = $dash->getPathInfo(PATHINFO_FILENAME); - $filename = $dash->getPathInfo(PATHINFO_FILENAME); + $filename = $this->dash->getPathInfo(PATHINFO_FILENAME); - $filter = [ + $this->filter = [ "-bf", "1", "-keyint_min", "120", "-g", "120", @@ -78,23 +78,25 @@ private function getBaseFilters(DASH $dash, int $count): array "-use_template", "1", "-init_seg_name", ($filename . '_init_$RepresentationID$.$ext$'), "-media_seg_name", ($filename . '_chunk_$RepresentationID$_$Number%05d$.$ext$'), - "-seg_duration", $dash->getSegDuration(), - "-hls_playlist", (int)$dash->isGenerateHlsPlaylist(), + "-seg_duration", $this->dash->getSegDuration(), + "-hls_playlist", (int)$this->dash->isGenerateHlsPlaylist(), "-f", "dash", ]; - if ($dash->getFormat() instanceof X264) { - $filter[] = "-profile:v:0"; - $filter[] = "main"; + if ($this->dash->getFormat() instanceof X264) { + $this->filter[] = "-profile:v:0"; + $this->filter[] = "main"; + + $count = count($this->dash->getRepresentations()); while ($count > 0) { - $filter[] = "-profile:v:" . $count; - $filter[] = "baseline"; + $this->filter[] = "-profile:v:" . $count; + $this->filter[] = "baseline"; $count--; } } - return $filter; + return $this->filter; } /** diff --git a/src/Filters/HLSFilter.php b/src/Filters/HLSFilter.php index 0d24366..18f8169 100644 --- a/src/Filters/HLSFilter.php +++ b/src/Filters/HLSFilter.php @@ -11,11 +11,12 @@ namespace Streaming\Filters; +use Streaming\StreamInterface; use Streaming\File; use Streaming\Representation; use Streaming\Utiles; -class HLSFilter extends Filter +class HLSFilter extends StreamFilter { /** @var \Streaming\HLS */ private $hls; @@ -97,7 +98,7 @@ private function getInitFilename(): string */ private function getSegmentFilename(Representation $rep): string { - $ext = ($this->hls->getHlsFmp4InitFilename() === "fmp4") ? "m4s" : "ts"; + $ext = ($this->hls->getHlsSegmentType() === "fmp4") ? "m4s" : "ts"; return $this->seg_filename . "_" . $rep->getHeight() . "p_%04d." . $ext; } @@ -169,12 +170,12 @@ private function setPaths(): void } /** - * @param $media + * @param StreamInterface $stream * @return void */ - public function setFilter($media): void + public function streamFilter(StreamInterface $stream): void { - $this->hls = $media; + $this->hls = $stream; $this->setPaths(); $reps = $this->hls->getRepresentations(); diff --git a/src/Filters/Filter.php b/src/Filters/StreamFilter.php similarity index 73% rename from src/Filters/Filter.php rename to src/Filters/StreamFilter.php index 28e72ed..f0897c4 100644 --- a/src/Filters/Filter.php +++ b/src/Filters/StreamFilter.php @@ -11,10 +11,9 @@ namespace Streaming\Filters; -use Streaming\Export; -use FFMpeg\Filters\FilterInterface; +use Streaming\StreamInterface; -abstract class Filter implements FilterInterface, FilterStreamingInterface +abstract class StreamFilter implements StreamFilterInterface { private $priority = 2; @@ -22,15 +21,15 @@ abstract class Filter implements FilterInterface, FilterStreamingInterface /** * Filter constructor. - * @param Export $media + * @param StreamInterface $stream */ - public function __construct(Export $media) + public function __construct(StreamInterface $stream) { - $this->setFilter($media); + $this->streamFilter($stream); } /** - * Applies the filter on the the Audio media given an format. + * Applies the filter on the the stream media * * @return array An array of arguments */ diff --git a/src/Filters/FilterStreamingInterface.php b/src/Filters/StreamFilterInterface.php similarity index 52% rename from src/Filters/FilterStreamingInterface.php rename to src/Filters/StreamFilterInterface.php index b25da78..205d6b8 100644 --- a/src/Filters/FilterStreamingInterface.php +++ b/src/Filters/StreamFilterInterface.php @@ -11,11 +11,19 @@ namespace Streaming\Filters; -interface FilterStreamingInterface +use FFMpeg\Filters\FilterInterface; +use Streaming\StreamInterface; + +interface StreamFilterInterface extends FilterInterface { /** - * @param $media + * @param StreamInterface $stream * @return mixed */ - public function setFilter($media): void; + public function streamFilter(StreamInterface $stream): void; + + /** + * @return array + */ + public function apply(): array; } \ No newline at end of file diff --git a/src/Filters/StreamToFileFilter.php b/src/Filters/StreamToFileFilter.php index fb9289f..731f0f7 100644 --- a/src/Filters/StreamToFileFilter.php +++ b/src/Filters/StreamToFileFilter.php @@ -13,26 +13,18 @@ namespace Streaming\Filters; +use Streaming\StreamInterface; use Streaming\StreamToFile; -class StreamToFileFilter extends Filter +class StreamToFileFilter extends StreamFilter { /** * @param $media * @return mixed */ - public function setFilter($media): void + public function streamFilter(StreamInterface $media): void { - $this->filter = $this->StreamToFileFilter($media); - } - - /** - * @param StreamToFile $stf - * @return array - */ - private function StreamToFileFilter(StreamToFile $stf) - { - return array_merge(['-c', 'copy'], $stf->getParams()); + $this->filter = array_merge(['-c', 'copy'], $media->getParams()); } } \ No newline at end of file diff --git a/src/HLS.php b/src/HLS.php index cff034d..f2f2bfa 100644 --- a/src/HLS.php +++ b/src/HLS.php @@ -11,9 +11,8 @@ namespace Streaming; -use phpDocumentor\Reflection\Types\This; -use Streaming\Filters\FilterStreamingInterface; use Streaming\Filters\HLSFilter; +use Streaming\Filters\StreamFilterInterface; class HLS extends Streaming { @@ -225,7 +224,7 @@ public function getHlsFmp4InitFilename(): string /** * @return HLSFilter */ - protected function getFilter(): FilterStreamingInterface + protected function getFilter(): StreamFilterInterface { return new HLSFilter($this); } diff --git a/src/Metadata.php b/src/Metadata.php index 5b5d1c4..df52779 100644 --- a/src/Metadata.php +++ b/src/Metadata.php @@ -14,16 +14,16 @@ use FFMpeg\FFProbe\DataMapping\Format; -use FFMpeg\FFProbe\DataMapping\Stream; +use FFMpeg\FFProbe\DataMapping\Stream as VideoStream; use FFMpeg\FFProbe\DataMapping\StreamCollection; use Streaming\Exception\InvalidArgumentException; class Metadata { /** - * @var Export + * @var Stream */ - private $export; + private $stream; /** * @var \FFMpeg\FFProbe\DataMapping\Format @@ -33,17 +33,17 @@ class Metadata /** * @var \FFMpeg\FFProbe\DataMapping\StreamCollection */ - private $streams_video; + private $video_streams; /** * Metadata constructor. - * @param Export $export + * @param Stream $stream */ - public function __construct(Export $export) + public function __construct(Stream $stream) { - $this->export = $export; - $this->format = $export->getMedia()->getFormat(); - $this->streams_video = $export->getMedia()->getStreams(); + $this->stream = $stream; + $this->format = $stream->getMedia()->getFormat(); + $this->video_streams = $stream->getMedia()->getStreams(); } /** @@ -59,14 +59,14 @@ public function getFormat(): Format */ public function getStreamsVideo(): StreamCollection { - return $this->streams_video; + return $this->video_streams; } /** - * @param Stream $stream + * @param VideoStream $stream * @return array */ - private function streamToArray(Stream $stream): array + private function streamToArray(VideoStream $stream): array { return $stream->all(); } @@ -100,11 +100,11 @@ private function repToArray(Representation $rep): array */ private function getResolutions(): array { - if (!method_exists($this->export, 'getRepresentations')) { + if (!method_exists($this->stream, 'getRepresentations')) { return []; } - return array_map([$this, 'repToArray'], $this->export->getRepresentations()); + return array_map([$this, 'repToArray'], $this->stream->getRepresentations()); } @@ -113,12 +113,12 @@ private function getResolutions(): array */ public function getStreamsMetadata(): array { - $dirname = $this->export->getPathInfo(PATHINFO_DIRNAME); - $basename = $this->export->getPathInfo(PATHINFO_BASENAME); + $dirname = $this->stream->getPathInfo(PATHINFO_DIRNAME); + $basename = $this->stream->getPathInfo(PATHINFO_BASENAME); $filename = $dirname . DIRECTORY_SEPARATOR . $basename; - $technique = explode("\\", get_class($this->export)); - $format = explode("\\", get_class($this->export->getFormat())); + $technique = explode("\\", get_class($this->stream)); + $format = explode("\\", get_class($this->stream->getFormat())); $metadata = [ "filename" => $filename, @@ -129,17 +129,17 @@ public function getStreamsMetadata(): array "streaming_technique" => end($technique) ]; - if ($this->export instanceof DASH) { - $metadata = array_merge($metadata, ["seg_duration" => $this->export->getSegDuration()]); - } elseif ($this->export instanceof HLS) { + if ($this->stream instanceof DASH) { + $metadata = array_merge($metadata, ["seg_duration" => $this->stream->getSegDuration()]); + } elseif ($this->stream instanceof HLS) { $metadata = array_merge( $metadata, [ - "hls_time" => (int)$this->export->getHlsTime(), - "hls_cache" => (bool)$this->export->isHlsAllowCache(), - "encrypted_hls" => (bool)$this->export->getHlsKeyInfoFile(), - "ts_sub_directory" => $this->export->getTsSubDirectory(), - "base_url" => $this->export->getHlsBaseUrl() + "hls_time" => (int)$this->stream->getHlsTime(), + "hls_cache" => (bool)$this->stream->isHlsAllowCache(), + "encrypted_hls" => (bool)$this->stream->getHlsKeyInfoFile(), + "ts_sub_directory" => $this->stream->getTsSubDirectory(), + "base_url" => $this->stream->getHlsBaseUrl() ] ); } @@ -166,12 +166,12 @@ public function get(): array public function saveAsJson(string $filename = null, int $opts = null): string { if (is_null($filename)) { - if ($this->export->isTmpDir()) { + if ($this->stream->isTmpDir()) { throw new InvalidArgumentException("It is a temp directory! It is not possible to save it"); } - $name = uniqid(($this->export->getPathInfo(PATHINFO_FILENAME) ?? "meta") . "-") . ".json"; - $filename = $this->export->getPathInfo(PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . $name; + $name = uniqid(($this->stream->getPathInfo(PATHINFO_FILENAME) ?? "meta") . "-") . ".json"; + $filename = $this->stream->getPathInfo(PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . $name; } file_put_contents( diff --git a/src/Export.php b/src/Stream.php similarity index 93% rename from src/Export.php rename to src/Stream.php index 07eadd2..50cf82f 100644 --- a/src/Export.php +++ b/src/Stream.php @@ -15,12 +15,11 @@ use Streaming\Clouds\Cloud; use Streaming\Exception\InvalidArgumentException; use Streaming\Exception\RuntimeException; -use Streaming\Filters\Filter; -use Streaming\Filters\FilterStreamingInterface; +use Streaming\Filters\StreamFilterInterface; use Streaming\Traits\Formats; -abstract class Export +abstract class Stream implements StreamInterface { use Formats; @@ -37,7 +36,7 @@ abstract class Export protected $uri; /** - * Export constructor. + * Stream constructor. * @param Media $media */ public function __construct(Media $media) @@ -64,9 +63,9 @@ public function isTmpDir(): bool /** * @param int $option - * @return array | string + * @return string */ - public function getPathInfo(int $option) + public function getPathInfo(int $option): string { return pathinfo($this->path, $option); } @@ -113,9 +112,9 @@ protected function getFilePath(): string abstract protected function getPath(): string; /** - * @return Filter + * @return StreamFilterInterface */ - abstract protected function getFilter(): FilterStreamingInterface; + abstract protected function getFilter(): StreamFilterInterface; /** * Run FFmpeg to package media content @@ -157,7 +156,7 @@ private function paths(?string $path, array $clouds): void * @param array $clouds * @return mixed */ - public function save(string $path = null, array $clouds = []) + public function save(string $path = null, array $clouds = []): Stream { $this->paths($path, $clouds); $this->run(); diff --git a/src/StreamInterface.php b/src/StreamInterface.php new file mode 100644 index 0000000..b14dfbd --- /dev/null +++ b/src/StreamInterface.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +namespace Streaming; + + +interface StreamInterface +{ + /** + * @return Media + */ + public function getMedia(): Media; + + /** + * @param int $option + * @return string + */ + public function getPathInfo(int $option): string; + + /** + * @param string $path + * @param array $clouds + * @return mixed + */ + public function save(string $path = null, array $clouds = []): Stream; + + /** + * @param string $url + */ + public function live(string $url): void; +} \ No newline at end of file diff --git a/src/StreamToFile.php b/src/StreamToFile.php index 033892c..73c3652 100644 --- a/src/StreamToFile.php +++ b/src/StreamToFile.php @@ -14,11 +14,10 @@ use Streaming\Exception\InvalidArgumentException; -use Streaming\Filters\Filter; -use Streaming\Filters\FilterStreamingInterface; +use Streaming\Filters\StreamFilterInterface; use Streaming\Filters\StreamToFileFilter; -class StreamToFile extends Export +class StreamToFile extends Stream { /** * @var array @@ -54,7 +53,7 @@ protected function getPath(): string /** * @return StreamToFileFilter */ - protected function getFilter(): FilterStreamingInterface + protected function getFilter(): StreamFilterInterface { if ($this->uri) { throw new InvalidArgumentException("It is not possible to live this file"); diff --git a/src/Streaming.php b/src/Streaming.php index 3ef8f91..6a81888 100644 --- a/src/Streaming.php +++ b/src/Streaming.php @@ -14,7 +14,7 @@ use Streaming\Traits\Representations; -abstract class Streaming extends Export +abstract class Streaming extends Stream { use Representations; @@ -34,7 +34,7 @@ public function getAdditionalParams(): array /** * @param array $additional_params - * @return Export + * @return Stream */ public function setAdditionalParams(array $additional_params) { @@ -44,9 +44,9 @@ public function setAdditionalParams(array $additional_params) /** * @param string $strict - * @return Export + * @return Stream */ - public function setStrict(string $strict): Export + public function setStrict(string $strict): Stream { $this->strict = $strict; return $this; diff --git a/tests/DASHFiltersTest.php b/tests/DASHFiltersTest.php index ecf7c2d..2f887ff 100644 --- a/tests/DASHFiltersTest.php +++ b/tests/DASHFiltersTest.php @@ -13,13 +13,13 @@ use Streaming\DASH; use Streaming\Filters\DASHFilter; -use Streaming\Filters\Filter; +use Streaming\Filters\StreamFilter; class DASHFiltersTest extends TestCase { public function testFilterClass() { - $this->assertInstanceOf(Filter::class, $this->getFilter()); + $this->assertInstanceOf(StreamFilter::class, $this->getFilter()); } public function testGetApply() diff --git a/tests/DASHTest.php b/tests/DASHTest.php index 93fdbc7..d9064b0 100644 --- a/tests/DASHTest.php +++ b/tests/DASHTest.php @@ -12,7 +12,7 @@ namespace Tests\FFMpegStreaming; use Streaming\DASH; -use Streaming\Export; +use Streaming\Stream; use Streaming\Format\Video; use Streaming\Representation; @@ -20,7 +20,7 @@ class DASHTest extends TestCase { public function testDASHClass() { - $this->assertInstanceOf(Export::class, $this->getDASH()); + $this->assertInstanceOf(Stream::class, $this->getDASH()); } public function testFormat() @@ -66,7 +66,7 @@ public function testSave() $this->assertFileExists($this->srcDir . '/dash/test.mpd'); - $this->assertInstanceOf(Export::class, $export_class); + $this->assertInstanceOf(Stream::class, $export_class); } private function getDASH() diff --git a/tests/HLSFiltersTest.php b/tests/HLSFiltersTest.php index 3b5cebe..34e6e47 100644 --- a/tests/HLSFiltersTest.php +++ b/tests/HLSFiltersTest.php @@ -11,7 +11,7 @@ namespace Tests\FFMpegStreaming; -use Streaming\Filters\Filter; +use Streaming\Filters\StreamFilter; use Streaming\Filters\HLSFilter; use Streaming\HLS; @@ -19,7 +19,7 @@ class HLSFiltersTest extends TestCase { public function testFilterClass() { - $this->assertInstanceOf(Filter::class, $this->getFilter()); + $this->assertInstanceOf(StreamFilter::class, $this->getFilter()); } private function getFilter() diff --git a/tests/HLSTest.php b/tests/HLSTest.php index f636a4a..809291c 100644 --- a/tests/HLSTest.php +++ b/tests/HLSTest.php @@ -12,7 +12,7 @@ namespace Tests\FFMpegStreaming; use Streaming\HLS; -use Streaming\Export; +use Streaming\Stream; use Streaming\Format\Video; use Streaming\Representation; use ReflectionClass; @@ -21,7 +21,7 @@ class HLSTest extends TestCase { public function testHLSClass() { - $this->assertInstanceOf(Export::class, $this->getHLS()); + $this->assertInstanceOf(Stream::class, $this->getHLS()); } public function testFormat()