Skip to content

Commit f3f6f1e

Browse files
add streaming analytics | bug fixes | some minor improvements
1 parent 2cd3130 commit f3f6f1e

15 files changed

+293
-45
lines changed

.appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ environment:
1616
COMPOSER_NO_INTERACTION: 1
1717
ANSICON: 121x90 (121x90) # Console colors
1818

19-
ffmpeg_download: https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20190225-f948082-win64-static.zip
19+
ffmpeg_download: https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20190725-923d5c4-win64-static.zip
2020

2121
matrix:
2222
- PHP_VERSION: 7.1

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,4 @@ install:
1818
- sudo apt-get install ffmpeg
1919

2020
script:
21-
- /usr/bin/ffmpeg -y -i /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test.mp4 -c:v libx264 -s:v 256x144 -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_list_size 0 -hls_time 5 -hls_allow_cache 1 -b:v 237k -maxrate 284k -hls_segment_filename /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_144p_%04d.ts -strict -2 /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_144p.m3u8 -s:v 426x240 -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_list_size 0 -hls_time 5 -hls_allow_cache 1 -b:v 292k -maxrate 350k -hls_segment_filename /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_240p_%04d.ts -strict -2 /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_240p.m3u8 -s:v 640x360 -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_list_size 0 -hls_time 5 -hls_allow_cache 1 -b:v 380k -maxrate 456k -hls_segment_filename /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_360p_%04d.ts -strict -2 /home/travis/build/aminyazdanpanah/PHP-FFmpeg-video-streaming/tests/files/test_360p.m3u8
2221
- vendor/bin/phpunit tests

README.md

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# 📼 PHP FFMPEG Video Streaming
22

33
[![Build Status](https://travis-ci.org/aminyazdanpanah/PHP-FFmpeg-video-streaming.svg?branch=master)](https://travis-ci.org/aminyazdanpanah/PHP-FFmpeg-video-streaming)
4-
[![Latest Version on Packagist](https://img.shields.io/packagist/v/aminyazdanpanah/php-ffmpeg-video-streaming.svg?style=flat-square)](https://packagist.org/packages/aminyazdanpanah/php-ffmpeg-video-streaming)
4+
[![Build status](https://img.shields.io/appveyor/ci/aminyazdanpanah/PHP-FFmpeg-video-streaming/master.svg?style=flat-square&logo=appveyor)](https://ci.appveyor.com/project/aminyazdanpanah/php-ffmpeg-video-streaming)
55
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aminyazdanpanah/PHP-FFmpeg-video-streaming/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aminyazdanpanah/PHP-FFmpeg-video-streaming/?branch=master)
6-
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/aminyazdanpanah/PHP-FFmpeg-video-streaming/blob/master/LICENSE)
76
[![Code Intelligence Status](https://scrutinizer-ci.com/g/aminyazdanpanah/PHP-FFmpeg-video-streaming/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence)
87
[![Total Downloads](https://img.shields.io/packagist/dt/aminyazdanpanah/php-ffmpeg-video-streaming.svg?style=flat-square)](https://packagist.org/packages/aminyazdanpanah/php-ffmpeg-video-streaming)
9-
[![Build status](https://img.shields.io/appveyor/ci/aminyazdanpanah/PHP-FFmpeg-video-streaming/master.svg?style=flat-square&logo=appveyor)](https://ci.appveyor.com/project/aminyazdanpanah/php-ffmpeg-video-streaming)
8+
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/aminyazdanpanah/PHP-FFmpeg-video-streaming/blob/master/LICENSE)
9+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/aminyazdanpanah/php-ffmpeg-video-streaming.svg?style=flat-square)](https://packagist.org/packages/aminyazdanpanah/php-ffmpeg-video-streaming)
1010

1111
This package provides an integration with [PHP-FFmpeg](https://github.com/PHP-FFMpeg/PHP-FFMpeg) and packages well-known live streaming techniques such as DASH and HLS. Also you can use DRM for HLS packaging.
1212

@@ -50,19 +50,21 @@ $listener = function ($audio, $format, $percentage) {
5050
//Also, it can be null-the default path is the input path.
5151
//These values are optional
5252
$output_path_dash = '/var/www/media/videos/test/dash/output.mpd'; //or null
53-
$output_path_hls = null; //or '/var/www/media/videos/test/hls/output.m3u8'
53+
$output_path_hls = null; //or '/var/www/media/videos/test/hls/output.m3u8';
54+
$output_path_encrypted_hls = '/var/www/media/videos/test/hls/output.m3u8'; // or null
5455

55-
//The path to the key info for encrypted hls.
56-
//This value is optional.
57-
$url_to_key = "https://www.aminyazdanpanah.com/enc.key"; //Path to get the key on your website
58-
$path_to_save_key = "/var/www/media/keys/my_key/enc.key"; //Path to save the random key on your server
59-
$hls_key_info = new Streaming\KeyInfo($url_to_key, $path_to_save_key);
56+
//Path to acceess the key on your website.
57+
// NOTE: It is highly recommended to protect the key using a token or a session/cookie.
58+
$url_to_key = "https://www.aminyazdanpanah.com/enc.key";
59+
//Path to save the random key on your server.
60+
$path_to_save_key = "/var/www/media/keys/my_key/enc.key";
6061

6162
$result_dash = dash($input_path, $output_path_dash, $listener); //Create dash files.
6263
$result_hls = hls($input_path, $output_path_hls, $listener, $hls_key_info); //Create hls files.
64+
$result_encrypted_hls = encrypted_hls($input_path, $output_path_encrypted_hls, $listener, $url_to_key, $path_to_save_key); //Create encrypted hls files
6365

6466
//dupm the results
65-
var_dump($result_dash, $result_hls);
67+
var_dump($result_dash, $result_hls, $result_encrypted_hls);
6668
```
6769

6870
## Documentation
@@ -216,28 +218,30 @@ Streaming\FFMpeg::create()
216218

217219
The encryption process requires some kind of secret (key) together with an encryption algorithm.
218220

219-
HLS uses AES in cipher block chaining (CBC) mode. This means each block is encrypted using the cipher text of the preceding block. [read more](http://hlsbook.net/how-to-encrypt-hls-video-with-ffmpeg/)
221+
HLS uses AES in cipher block chaining (CBC) mode. This means each block is encrypted using the cipher text of the preceding block. [learn more](http://hlsbook.net/how-to-encrypt-hls-video-with-ffmpeg/)
220222

221223
Before we can encrypt videos, we need an encryption key. However you can use any software that can generate key, this package requires a working OpenSSL to create the key:
222224

223-
``` php
224-
$url_to_key = "https://www.aminyazdanpanah.com/enc.key"; //Path to get the key on your website
225-
$path_to_save_key = "/var/www/media/keys/my_key/enc.key"; //Path to save the random key on your server
226-
$hls_key_info = new Streaming\KeyInfo($url_to_key, $path_to_save_key);
227-
```
228-
- **NOTE:** It is recommended to protect your key on your website using a token or a session/cookie.
225+
Getting OpenSSL: https://www.openssl.org/source/
226+
227+
Getting OpenSSL(Windows): https://slproweb.com/products/Win32OpenSSL.html
229228

230229
The next step is to pass key info to `setHlsKeyInfoFile` method:
231230
``` php
231+
$url = "https://www.aminyazdanpanah.com/enc.key"; //Path to access the key on your website
232+
$path = "/var/www/media/keys/my_key/enc.key"; //Path to save the random key on your server
233+
232234
Streaming\FFMpeg::create()
233235
->open('/var/www/media/videos/test.mp4')
234236
->HLS()
235237
->X264()
236-
->setHlsKeyInfoFile($hls_key_info)
238+
->generateRandomKeyInfo($url, $path)
237239
->autoGenerateRepresentations()
238240
->save('/var/www/media/videos/hls/test.m3u8');
239241
```
240-
- **Note:** Alternatively, you can generate a key info using another library and pass the path to the method.
242+
- **Note:** Alternatively, you can generate a key info using another library and pass the path to the `setHlsKeyInfoFile` method.
243+
- **NOTE:** It is highly recommended to protect your key on your website using a token or a session/cookie (e.x. https://wwww.aminyazdanpanah.com/enc.key?tk=J5HLhi97Tjk4N).
244+
- **NOTE:** For getting the benefit of the OpenSSL binary detection in windows, you need to add it to your system path otherwise, you have to pass the path to OpenSSL binary to the `generateRandomKeyInfo` method explicitly.
241245

242246
### Other Advanced Features
243247
You can easily use other advanced features in the [PHP-FFMpeg](https://github.com/PHP-FFMpeg/PHP-FFMpeg) library. In fact, when you open a file with `open` method, it holds the Media object that belongs to the PHP-FFMpeg.

composer.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aminyazdanpanah/php-ffmpeg-video-streaming",
3-
"description": "📹📼 PHP FFMpeg - Video Streaming - DASH, HLS http://video.aminyazdanpanah.com",
3+
"description": "📼 PHP FFMpeg - Video Streaming - DASH, HLS http://video.aminyazdanpanah.com",
44
"type": "library",
55
"keywords": [
66
"dash",
@@ -10,6 +10,9 @@
1010
"streaming",
1111
"chunk",
1212
"live",
13+
"media",
14+
"video-streaming",
15+
"live-streaming",
1316
"AminYazdanpanah",
1417
"DynamicAdaptiveStreamingOverHTTP"
1518
],
@@ -20,7 +23,7 @@
2023
{
2124
"name": "Amin Yazdanpanah",
2225
"email": "contact@aminyazdanpanah.com",
23-
"homepage": "http://www.aminyazdanpanah.com"
26+
"homepage": "https://www.aminyazdanpanah.com"
2427
}
2528
],
2629
"minimum-stability": "dev",
@@ -45,7 +48,7 @@
4548
},
4649
"require": {
4750
"php": "^7.1",
48-
"php-ffmpeg/php-ffmpeg": "^0.13"
51+
"php-ffmpeg/php-ffmpeg": "^0.14"
4952
},
5053
"scripts": {
5154
"test": "vendor/bin/phpunit"

src/AutoRepresentations.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@ class AutoRepresentations
1919
/** @var Stream $stream */
2020
private $stream;
2121

22-
/** @Const regular video's heights */
23-
private const heights = [2160, 1080, 720, 480, 240, 144];
22+
/** @var array side_values
23+
* regular video's heights
24+
*/
25+
private $side_values = [2160, 1080, 720, 480, 240, 144];
2426

2527
/**
2628
* AutoRepresentations constructor.
2729
* @param Stream $stream
30+
* @param null $side_values
2831
*/
29-
public function __construct(Stream $stream)
32+
public function __construct(Stream $stream, $side_values)
3033
{
34+
if(null !== $side_values){
35+
$this->side_values = $side_values;
36+
}
37+
3138
$this->stream = $stream;
3239
}
3340

@@ -65,7 +72,7 @@ public function get(): array
6572

6673
$representations[] = $this->addRepresentation($kilobitrate, $width, $height);
6774

68-
$heights = array_filter(static::heights, function ($value) use ($height) {
75+
$heights = array_filter($this->side_values, function ($value) use ($height) {
6976
return $value < $height;
7077
});
7178

src/Export.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ abstract class Export
3434
public function __construct(Media $media)
3535
{
3636
$this->media = $media;
37-
$this->path_info = $media->getPathInfo();
37+
$this->path_info = pathinfo($media->getPath());
3838
}
3939

4040
/**
4141
* @param string $path
42-
* @return Export
42+
* @param bool $analyse
43+
* @param bool $delete_original_video
44+
* @return mixed
4345
*/
44-
public function save(string $path = null): Export
46+
public function save(string $path = null, $analyse = true, $delete_original_video = false)
4547
{
4648
$path = $this->getPath($path);
4749

@@ -56,7 +58,12 @@ public function save(string $path = null): Export
5658
$path
5759
);
5860

59-
return $this;
61+
if ($delete_original_video) {
62+
sleep(1);
63+
@unlink($this->media->getPath());
64+
}
65+
66+
return ($analyse) ? (new StreamingAnalytics($this))->analyse() : $path;
6067
}
6168

6269
/**
@@ -71,7 +78,7 @@ abstract protected function setFilter();
7178

7279
private function getPath($path): string
7380
{
74-
if(null !== $path){
81+
if (null !== $path) {
7582
$this->path_info = pathinfo($path);
7683
}
7784

@@ -98,4 +105,12 @@ public function getPathInfo(): array
98105
{
99106
return $this->path_info;
100107
}
108+
109+
/**
110+
* @return object|Media
111+
*/
112+
public function getMedia()
113+
{
114+
return $this->media;
115+
}
101116
}

src/HLS.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ public function setHlsKeyInfoFile(string $hls_key_info_file): HLS
7474
return $this;
7575
}
7676

77+
/**
78+
* @param string $url
79+
* @param string $path
80+
* @param string $binary
81+
* @return HLS
82+
* @throws Exception\Exception
83+
*/
84+
public function generateRandomKeyInfo(string $url = null, string $path = null, string $binary = "openssl"): HLS
85+
{
86+
if (null === $url && null === $path){
87+
$key_name = $url = Helper::randomString() . ".key";
88+
$path = $this->path_info["dirname"] . DIRECTORY_SEPARATOR . $key_name;
89+
}
90+
91+
$this->hls_key_info_file = (string) new KeyInfo($url, $path, $binary);
92+
return $this;
93+
}
94+
7795
/**
7896
* @return string
7997
*/

src/Helper.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Streaming;
1313

14+
1415
class Helper
1516
{
1617
/**
@@ -35,10 +36,31 @@ public static function makeDir($dirname): void
3536
}
3637
}
3738

39+
/**
40+
* @param int $length
41+
* @return bool|string
42+
*/
3843
public static function randomString($length = 10)
3944
{
4045
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
4146
return substr(str_shuffle(str_repeat($chars, ceil($length / strlen($chars)))), 1, $length);
4247

4348
}
49+
50+
/**
51+
* @param $dir
52+
* @return int|null
53+
*/
54+
public static function directorySize($dir)
55+
{
56+
if (is_dir($dir)) {
57+
$size = 0;
58+
foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
59+
$size += is_file($each) ? filesize($each) : static::directorySize($each);
60+
}
61+
return $size;
62+
}
63+
64+
return null;
65+
}
4466
}

src/KeyInfo.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class KeyInfo
3333
* @param string $binary
3434
* @throws Exception\Exception
3535
*/
36-
public function __construct($url, $path, $binary = "openssl")
36+
public function __construct(string $url, string $path, $binary = "openssl")
3737
{
3838
$this->url = $url;
3939
$this->path = $path;
@@ -84,6 +84,6 @@ private function generateRandomKey(): string
8484
*/
8585
private function generateIV(): string
8686
{
87-
return $this->openssl->removeCommand('16')->addCommand(['-hex' ,'16'])->run();
87+
return $this->openssl->reset()->addCommand(['rand', '-hex' ,'16'])->run();
8888
}
8989
}

src/Media.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,24 @@ public function __call($method, $parameters)
7979
/**
8080
* @return mixed
8181
*/
82-
public function getFirstStream(): Stream
82+
public function getVideoStream(): Stream
8383
{
84-
return $this->media->getStreams()->first();
84+
return $this->media->getStreams()->videos()->first();
8585
}
8686

8787
/**
88-
* @return array
88+
* @return mixed
89+
*/
90+
public function getAllStreams()
91+
{
92+
return $this->media->getStreams()->all();
93+
}
94+
95+
/**
96+
* @return string
8997
*/
90-
public function getPathInfo(): array
98+
public function getPath(): string
9199
{
92-
return pathinfo($this->path);
100+
return $this->path;
93101
}
94102
}

src/Process/Process.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public function addCommand($command): Process
9191
} else {
9292
$this->commands[] = $command;
9393
}
94+
9495
return $this;
9596
}
9697

@@ -114,4 +115,13 @@ public function getCommand(): array
114115
{
115116
return $this->commands;
116117
}
118+
119+
/**
120+
* @return Process
121+
*/
122+
public function reset()
123+
{
124+
$this->commands = [current($this->commands)];
125+
return $this;
126+
}
117127
}

0 commit comments

Comments
 (0)