Skip to content

Commit

Permalink
add auto generate rep
Browse files Browse the repository at this point in the history
fixes some minor bugs
  • Loading branch information
aminyazdanpanah committed Jan 31, 2019
1 parent bea08eb commit 95defb3
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 62 deletions.
90 changes: 55 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PHP FFMPEG Video Streaming

This package provides an integration with FFmpeg and exports well-known video streaming such as DASH, HLS, and Live Streaming.
This package provides an integration with [PHP-FFmpeg](https://github.com/PHP-FFMpeg/PHP-FFMpeg) and exports well-known video streaming techniques such as DASH, HLS, and Live Streaming(DASH,HLS).

## Features
* Easily exports all your videos into DASH, HLS, and Live video streaming.
Expand Down Expand Up @@ -28,55 +28,75 @@ use AYazdanpanah\FFMpegStreaming\FFMpeg

``` php
$config = [
'ffmpeg.binaries' => '/usr/local/bin/ffmpeg', // the path to the FFMpeg binary
'ffprobe.binaries' => '/usr/local/bin/ffprobe', // the path to the FFProbe binary
'timeout' => 3600, // the timeout for the underlying process
'ffmpeg.threads' => 12, // the number of threads that FFMpeg should use
'ffmpeg.binaries' => '/usr/local/bin/ffmpeg', // the path to the FFMpeg binary
'ffprobe.binaries' => '/usr/local/bin/ffprobe', // the path to the FFProbe binary
'timeout' => 3600, // the timeout for the underlying process
'ffmpeg.threads' => 12, // the number of threads that FFMpeg should use
];

$ffmpeg = new FFMpeg($config);
```

## DASH

You can create an MPD playlist to do [DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP).

As of version 1.1.0 the ```autoGenerateRepresentations``` method has been added. This method allows you to auto generate multi representations base on original video size and bit rate:

``` php
$ffmpeg->open('/var/www/media/videos/test.mp4') // the path to the video
->DASH()
->X264()
->autoGenerateRepresentations()
->setAdaption('id=0,streams=v id=1,streams=a')
->save();
```

or you can add representation manually by ```addRepresentation``` method:

``` php
try {
$rep_1 = (new Representation())->setKiloBitrate(800);
$rep_2 = (new Representation())->setKiloBitrate(300)->setResize(320 , 170);
$ffmpeg->open('/var/www/media/videos/test.mp4')
->DASH()
->X264()
->addRepresentation($rep_1)
->addRepresentation($rep_2)
->setAdaption('id=0,streams=v id=1,streams=a')
->save('/var/www/media/videos/test.mpd');
} catch (Exception $e) {
echo $e->getMassege();
}
$rep_1 = (new Representation())->setKiloBitrate(800);
$rep_2 = (new Representation())->setKiloBitrate(300)->setResize(320 , 170);

$ffmpeg->open('/var/www/media/videos/test.mp4') // the path to the video
->DASH()
->X264()
->addRepresentation($rep_1)
->addRepresentation($rep_2)
->setAdaption('id=0,streams=v id=1,streams=a')
->save();

```

For more information about [FFMpeg](https://ffmpeg.org/) and its dash parameters please [click here](https://ffmpeg.org/ffmpeg-formats.html#dash-2).
## HLS

Create an M3U8 playlist to do [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming).
As of version 1.1.0 the ```autoGenerateRepresentations``` method has been added. This method allows you to auto generate multi representations base on original video size and bit rate:

``` php
$ffmpeg->open('/var/www/media/videos/test.mp4') // the path to the video
->HLS()
->X264()
->autoGenerateRepresentations()
->setAdaption('id=0,streams=v id=1,streams=a')
->save();
```

or you can add representation manually by ```addRepresentation``` method:

``` php
try {
$rep_1 = (new Representation())->setKiloBitrate(1000);
$rep_2 = (new Representation())->setKiloBitrate(500)->setResize(640 , 360);
$rep_3 = (new Representation())->setKiloBitrate(200)->setResize(480 , 240);
$ffmpeg->open('/var/www/media/videos/test.mp4')
->HLS()
->X264()
->addRepresentation($rep_1)
->addRepresentation($rep_2)
->addRepresentation($rep_3)
->setStreamMap('v:0,a:0 v:1,a:1')
->save('/var/www/media/videos/test.m3u8');
} catch (Exception $e) {
echo $e->getMassege();
}
$rep_1 = (new Representation())->setKiloBitrate(1000);
$rep_2 = (new Representation())->setKiloBitrate(500)->setResize(640 , 360);
$rep_3 = (new Representation())->setKiloBitrate(200)->setResize(480 , 240);

$ffmpeg->open('/var/www/media/videos/test.mp4') // the path to the video
->HLS()
->X264()
->addRepresentation($rep_1)
->addRepresentation($rep_2)
->addRepresentation($rep_3)
->setStreamMap('v:0,a:0 v:1,a:1')
->save();
```

## Live Streaming
Expand All @@ -102,4 +122,4 @@ If you discover a security vulnerability within this package, please send an e-m

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
The MIT License (MIT). Please see [License File](https://github.com/aminyazdanpanah/PHP-FFmpeg-video-streaming/blob/master/LICENSE) for more information.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@

"require": {
"php": "^7.1.0",
"php-ffmpeg/php-ffmpeg": "^0.13.0"
"php-ffmpeg/php-ffmpeg": "^0.7.0@dev"
}
}
118 changes: 118 additions & 0 deletions src/AutoRepresentations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

namespace AYazdanpanah\FFMpegStreaming;

use AYazdanpanah\FFMpegStreaming\Exception\Exception;
use FFMpeg\Coordinate\Dimension;
use FFMpeg\FFProbe\DataMapping\Stream;

class AutoRepresentations
{
private $stream;

/**
* AutoRepresentations constructor.
* @param Stream $stream
*/
public function __construct(Stream $stream)
{
$this->stream = $stream;
}

/**
* @return Dimension
*/
private function getDimensions(): Dimension
{
return $this->stream->getDimensions();
}

/**
* @return mixed
* @throws Exception
*/
private function getKiloBitRate(): int
{
if (!$this->stream->has('bit_rate')) {
throw new Exception("Invalid stream");
}
return (int)$this->stream->get('bit_rate') / 1000;
}

/**
* @return array
* @throws Exception
*/
public function get(): array
{
$dimension = $this->getDimensions();

$width = $dimension->getWidth();
$height = $dimension->getHeight();

$param = [
'aspect_ratio' => $width / $height,
'bit_rate' => $this->getKiloBitRate(),
];

if ($height > 1050) {
$representations = [
$this->addRepresentation($param, 4, 240),
$this->addRepresentation($param, 2, 480),
$this->addRepresentation($param, 4 / 3, 720),
$this->addRepresentation($param, 1, $height)
];
} elseif ($height > 700) {
$representations = [
$this->addRepresentation($param, 4, 240),
$this->addRepresentation($param, 2, 360),
$this->addRepresentation($param, 4 / 3, 480),
$this->addRepresentation($param, 1, $height)
];
} elseif ($height > 450) {
$representations = [
$this->addRepresentation($param, 4, 144),
$this->addRepresentation($param, 2, 240),
$this->addRepresentation($param, 4 / 3, 360),
$this->addRepresentation($param, 1, $height)
];
} elseif ($height > 330) {
$representations = [
$this->addRepresentation($param, 3, 144),
$this->addRepresentation($param, 3 / 2, 240),
$this->addRepresentation($param, 1, $height),
null
];
} elseif ($height > 210) {
$representations = [
$this->addRepresentation($param, 2, 144),
$this->addRepresentation($param, 1, $height),
];
} else {
$representations = [
$this->addRepresentation($param, 1, $height),
];
}

return $representations;
}

/**
* @param $param
* @param $divide
* @param $height
* @return Representation
* @internal param $aspect_ratio
* @throws Exception
*/
private function addRepresentation($param, $divide, $height): Representation
{
$width = intval($height * $param['aspect_ratio']);

if ($width % 2 == 1) $width++;

return (new Representation())
->setKiloBitrate(intval($param['bit_rate'] / $divide))
->setResize($width, $height);
}
}
8 changes: 0 additions & 8 deletions src/DASH.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ public function setAdaption(string $adaption): DASH
return $this;
}

/**
* @return array
*/
public function getRepresentations(): array
{
return $this->representations;
}

/**
* @return Filter
*/
Expand Down
40 changes: 34 additions & 6 deletions src/Export.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ abstract class Export
/** @var object */
protected $media;

/** @var object */
protected $format;

/** @var Filter */
protected $filter;

Expand All @@ -37,6 +34,26 @@ public function addRepresentation(Representation $representation): Export
return $this;
}

/**
* @return array
*/
public function getRepresentations(): array
{
return $this->representations;
}

/**
* @return $this
* @throws Exception
*/
public function autoGenerateRepresentations()
{
$this->representations = (new AutoRepresentations($this->media->getFirstStream()))
->get();

return $this;
}

/**
* Export constructor.
* @param Media $media
Expand Down Expand Up @@ -68,7 +85,7 @@ protected function setFormat($format): Export
* @param string $path
* @return Export
*/
public function save(string $path): Export
public function save(string $path = null): Export
{
$this->setFilter();

Expand All @@ -78,7 +95,7 @@ public function save(string $path): Export

$this->media->save(
$this->getFormat(),
$path
$this->getPath($path)
);

return $this;
Expand All @@ -89,10 +106,21 @@ public function save(string $path): Export
*/
abstract protected function getFilter(): Filter;


/**
* @return mixed
*/
abstract protected function setFilter();

private function getPath($path): string
{
if (null === $path) {
if ($this instanceof DASH) {
$path = $this->media->getPath() . '.mpd';
} elseif ($this instanceof HLS) {
$path = $this->media->getPath() . '.m3u8';
}
}

return $path;
}
}
2 changes: 1 addition & 1 deletion src/FFMpeg.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct($config, $logger = null)
*/
public function open($path): Media
{
return new Media($this->ffmpeg->open($path));
return new Media($this->ffmpeg->open($path), $path);
}

/**
Expand Down
8 changes: 0 additions & 8 deletions src/HLS.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ public function setStreamMap(string $adaption): HLS
return $this;
}

/**
* @return array
*/
public function getRepresentations(): array
{
return $this->representations;
}

/**
* @return Filter
*/
Expand Down
Loading

0 comments on commit 95defb3

Please sign in to comment.