Merge branch 'release-0.7.2-beta2'
This commit is contained in:
commit
8c58c379de
20 changed files with 1145 additions and 251 deletions
|
@ -6,6 +6,7 @@ install:
|
|||
- composer install
|
||||
before_install:
|
||||
- npm install -g npm@3
|
||||
script: vendor/bin/phpunit
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
before_deploy:
|
||||
|
|
|
@ -5,12 +5,12 @@ RUN apt-get install -y libicu-dev xz-utils git zlib1g-dev python nodejs
|
|||
RUN docker-php-ext-install mbstring
|
||||
RUN docker-php-ext-install intl
|
||||
RUN docker-php-ext-install zip
|
||||
RUN npm install -g bower grunt-cli
|
||||
RUN a2enmod rewrite
|
||||
RUN curl -sS https://getcomposer.org/installer | php
|
||||
COPY php.ini /usr/local/etc/php/
|
||||
COPY . /var/www/html/
|
||||
RUN php composer.phar install --prefer-dist
|
||||
RUN npm install
|
||||
RUN bower --allow-root install
|
||||
RUN grunt
|
||||
RUN ./node_modules/.bin/bower --allow-root install
|
||||
RUN ./node_modules/.bin/grunt
|
||||
ENV CONVERT=1
|
||||
|
|
76
FAQ.md
76
FAQ.md
|
@ -12,15 +12,15 @@ You can ususally download the video by doing *File > Save to* or *ctrl + S*.
|
|||
You need to create a YAML file called `config.yml` at the root of your project.
|
||||
Here are the parameters that you can set:
|
||||
|
||||
* youtubedl: path to your youtube-dl binary
|
||||
* python: path to your python binary
|
||||
* params: an array of parameters to pass to youtube-dl
|
||||
* curl_params: an array of parameters to pass to curl
|
||||
* convert: true to enable audio conversion
|
||||
* avconv: path to your avconv or ffmpeg binary
|
||||
* rtmpdump: path to your rtmpdump binary
|
||||
* `youtubedl`: path to your youtube-dl binary
|
||||
* `python`: path to your python binary
|
||||
* `params`: an array of parameters to pass to youtube-dl
|
||||
* `curl_params`: an array of parameters to pass to curl
|
||||
* `convert`: true to enable audio conversion
|
||||
* `avconv`: path to your avconv or ffmpeg binary
|
||||
* `rtmpdump`: path to your rtmpdump binary
|
||||
|
||||
See [config.example.yml](config.example.yml) for default values.
|
||||
See [`config.example.yml`](config.example.yml) for default values.
|
||||
|
||||
## How do I enable audio conversion?
|
||||
|
||||
|
@ -61,7 +61,7 @@ Some websites generate an unique video URL for each IP address. When using Alltu
|
|||
There are two known workarounds:
|
||||
|
||||
* You can run Alltube locally on your computer.
|
||||
* You can use the experimental `feature/stream` branch which streams the video through the server in order to bypass IP restrictions.
|
||||
* You can enable streaming videos through the server (see below).
|
||||
Please note that this can use a lot of resources on the server (which is why we won't enable it on alltubedownload.net).
|
||||
|
||||
## CSS and JavaScript files are missing
|
||||
|
@ -71,3 +71,61 @@ You need to either:
|
|||
|
||||
* Use a [release package](https://github.com/Rudloff/alltube/releases)
|
||||
* Run `npm install` (see detailed instructions in the [README](README.md#from-git))
|
||||
|
||||
## I get a 404 error on every page except the index
|
||||
|
||||
This is probably because your server does not have mod_rewrite or AllowOverride is disabled.
|
||||
You can work around this by adding this to your `config.yml` file:
|
||||
|
||||
```yaml
|
||||
uglyUrls: true
|
||||
```
|
||||
|
||||
## How do I enable streaming videos through the server?
|
||||
|
||||
You need to add this to your `config.yml` file:
|
||||
|
||||
```yaml
|
||||
stream: true
|
||||
```
|
||||
|
||||
Note that this can use a lot of ressources on your server.
|
||||
|
||||
## I want to download M3U videos
|
||||
|
||||
You need to enable streaming (see above).
|
||||
|
||||
## The downloaded videos have a strange name like `videoplayback.mp4`
|
||||
|
||||
Alltube can rename videos automatically if you enable streaming (see above).
|
||||
|
||||
## I want to download a video that isn't available in my country
|
||||
|
||||
If the video is available in the server's country, you can download it if you enable streaming (see above).
|
||||
|
||||
## How do I run the Docker image?
|
||||
|
||||
```bash
|
||||
docker run -p 8080:80 rudloff/alltube
|
||||
```
|
||||
|
||||
## How do I run Heroku locally?
|
||||
|
||||
You should be able to use `heroku local` like this:
|
||||
|
||||
```bash
|
||||
sudo APACHE_LOCK_DIR=. APACHE_PID_FILE=./pid APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data APACHE_LOG_DIR=. heroku local
|
||||
```
|
||||
|
||||
You might need to create some symlinks before that:
|
||||
|
||||
```bash
|
||||
ln -s /usr/sbin/apache2 /usr/sbin/httpd
|
||||
ln -s /usr/sbin/php-fpm7.0 /usr/sbin/php-fpm
|
||||
```
|
||||
|
||||
And you probably need to run this in another terminal after `heroku local` has finished launching `php-fpm`:
|
||||
|
||||
```bash
|
||||
chmod 0667 /tmp/heroku.fcgi.5000.sock
|
||||
```
|
||||
|
|
10
README.md
10
README.md
|
@ -33,6 +33,16 @@ chmod 777 templates_c/
|
|||
|
||||
If your web server is Apache, you need to set the `AllowOverride` setting to `All` or `FileInfo`.
|
||||
|
||||
#### Update
|
||||
|
||||
When updating from Git, you need to run npm and Composer again:
|
||||
|
||||
```bash
|
||||
git pull
|
||||
npm install
|
||||
composer install
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
If you want to use a custom config, you need to create a config file:
|
||||
|
|
|
@ -38,7 +38,7 @@ class Config
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public $params = ['--no-playlist', '--no-warnings', '-f best[protocol^=http]', '--playlist-end', 1];
|
||||
public $params = ['--no-playlist', '--no-warnings', '--playlist-end', 1];
|
||||
|
||||
/**
|
||||
* Enable audio conversion.
|
||||
|
@ -82,6 +82,13 @@ class Config
|
|||
*/
|
||||
public $uglyUrls = false;
|
||||
|
||||
/**
|
||||
* Stream downloaded files trough server?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $stream = false;
|
||||
|
||||
/**
|
||||
* YAML config file path.
|
||||
*
|
||||
|
|
|
@ -295,4 +295,33 @@ class VideoDownload
|
|||
|
||||
return popen($chain->getProcess()->getCommandLine(), 'r');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get video stream from an M3U playlist.
|
||||
*
|
||||
* @param \stdClass $video Video object returned by getJSON
|
||||
*
|
||||
* @return resource popen stream
|
||||
*/
|
||||
public function getM3uStream(\stdClass $video)
|
||||
{
|
||||
if (!shell_exec('which '.$this->config->avconv)) {
|
||||
throw(new \Exception('Can\'t find avconv or ffmpeg'));
|
||||
}
|
||||
|
||||
$procBuilder = ProcessBuilder::create(
|
||||
[
|
||||
$this->config->avconv,
|
||||
'-v', 'quiet',
|
||||
'-i', $video->url,
|
||||
'-f', $video->ext,
|
||||
'-c', 'copy',
|
||||
'-bsf:a', 'aac_adtstoasc',
|
||||
'-movflags', 'frag_keyframe+empty_moov',
|
||||
'pipe:1',
|
||||
]
|
||||
);
|
||||
|
||||
return popen($procBuilder->getProcess()->getCommandLine(), 'r');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
"symfony/process": "~3.2.0",
|
||||
"ptachoire/process-builder-chain": "~1.2.0",
|
||||
"rudloff/smarty-plugin-noscheme": "~0.1.0",
|
||||
"guzzlehttp/guzzle": "~6.2.0",
|
||||
"rudloff/rtmpdump-bin": "~2.3",
|
||||
"aura/session": "~2.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -19,7 +21,7 @@
|
|||
"squizlabs/php_codesniffer": "~2.7.0",
|
||||
"phpunit/phpunit": "~5.7.2",
|
||||
"ffmpeg/ffmpeg": "dev-release",
|
||||
"rg3/youtube-dl": "~2017.01.10",
|
||||
"rg3/youtube-dl": "~2017.03.07",
|
||||
"rudloff/rtmpdump-bin": "~2.3",
|
||||
"heroku/heroku-buildpack-php": "*"
|
||||
},
|
||||
|
@ -35,10 +37,10 @@
|
|||
"type": "package",
|
||||
"package": {
|
||||
"name": "rg3/youtube-dl",
|
||||
"version": "2017.01.10",
|
||||
"version": "2017.03.07",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/rg3/youtube-dl/archive/2017.01.10.zip"
|
||||
"url": "https://github.com/rg3/youtube-dl/archive/2017.03.07.zip"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -48,7 +50,7 @@
|
|||
"name": "ffmpeg/ffmpeg",
|
||||
"version": "dev-release",
|
||||
"dist": {
|
||||
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||
"url": "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||
"type": "xz"
|
||||
},
|
||||
"bin": [
|
||||
|
@ -77,9 +79,6 @@
|
|||
"Alltube\\Controller\\": "controllers/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"secure-http": false
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "composer install --dev"
|
||||
}
|
||||
|
|
495
composer.lock
generated
495
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "16268cc5135ed42aedf75446f4e39bd7",
|
||||
"content-hash": "1ac742cf7c2832a7af628c157ced2dbc",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aura/session",
|
||||
|
@ -70,18 +70,21 @@
|
|||
},
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/container-interop/container-interop.git",
|
||||
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
|
||||
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
||||
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
||||
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@ -93,7 +96,186 @@
|
|||
"MIT"
|
||||
],
|
||||
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
||||
"time": "2014-12-30T15:22:37+00:00"
|
||||
"homepage": "https://github.com/container-interop/container-interop",
|
||||
"time": "2017-02-14T19:40:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
|
||||
"reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/promises": "^1.0",
|
||||
"guzzlehttp/psr7": "^1.4",
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "^4.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle is a PHP HTTP client library",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"client",
|
||||
"curl",
|
||||
"framework",
|
||||
"http",
|
||||
"http client",
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2017-02-28T22:50:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "v1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle promises library",
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"time": "2016-12-20T10:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/0d6c7ca039329247e4f0f8f8f6506810e8248855",
|
||||
"reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"psr/http-message": "~1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Psr7\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "PSR-7 message implementation that also provides common utility methods",
|
||||
"keywords": [
|
||||
"http",
|
||||
"message",
|
||||
"request",
|
||||
"response",
|
||||
"stream",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2017-02-27T10:51:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jeremykendall/php-domain-parser",
|
||||
|
@ -273,16 +455,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"version": "v1.1.0",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/FastRoute.git",
|
||||
"reference": "f3dcf5130e634b6123d40727d612ec6aa4f61fb3"
|
||||
"reference": "b5f95749071c82a8e0f58586987627054400cdf6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/f3dcf5130e634b6123d40727d612ec6aa4f61fb3",
|
||||
"reference": "f3dcf5130e634b6123d40727d612ec6aa4f61fb3",
|
||||
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/b5f95749071c82a8e0f58586987627054400cdf6",
|
||||
"reference": "b5f95749071c82a8e0f58586987627054400cdf6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -312,7 +494,7 @@
|
|||
"router",
|
||||
"routing"
|
||||
],
|
||||
"time": "2016-10-20T17:36:47+00:00"
|
||||
"time": "2017-01-19T11:35:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
|
@ -360,6 +542,55 @@
|
|||
],
|
||||
"time": "2015-09-11T15:10:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"time": "2017-02-14T16:28:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
|
@ -446,6 +677,34 @@
|
|||
"description": "Add ability to chain symfony processes",
|
||||
"time": "2016-04-10T08:33:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rudloff/rtmpdump-bin",
|
||||
"version": "2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rudloff/rtmpdump-bin.git",
|
||||
"reference": "133cdd80e3bab66593e88a5276158596383afd97"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Rudloff/rtmpdump-bin/zipball/133cdd80e3bab66593e88a5276158596383afd97",
|
||||
"reference": "133cdd80e3bab66593e88a5276158596383afd97",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"rtmpdump/rtmpdump": "2.3"
|
||||
},
|
||||
"bin": [
|
||||
"rtmpdump"
|
||||
],
|
||||
"type": "library",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-2.0"
|
||||
],
|
||||
"description": "rtmpdump binary for Linux 64 bit",
|
||||
"time": "2016-04-12T19:17:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rudloff/smarty-plugin-noscheme",
|
||||
"version": "0.1.1",
|
||||
|
@ -612,16 +871,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "02ea84847aad71be7e32056408bb19f3a616cdd3"
|
||||
"reference": "68bfa8c83f24c0ac04ea7193bcdcda4519f41892"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/02ea84847aad71be7e32056408bb19f3a616cdd3",
|
||||
"reference": "02ea84847aad71be7e32056408bb19f3a616cdd3",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/68bfa8c83f24c0ac04ea7193bcdcda4519f41892",
|
||||
"reference": "68bfa8c83f24c0ac04ea7193bcdcda4519f41892",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -657,20 +916,20 @@
|
|||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-11-24T10:40:28+00:00"
|
||||
"time": "2017-03-04T12:23:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "a7095af4b97a0955f85c8989106c249fa649011f"
|
||||
"reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f",
|
||||
"reference": "a7095af4b97a0955f85c8989106c249fa649011f",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/093e416ad096355149e265ea2e4cc1f9ee40ab1a",
|
||||
"reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -712,7 +971,7 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-12-10T10:07:06+00:00"
|
||||
"time": "2017-03-07T16:47:02+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -775,7 +1034,7 @@
|
|||
"version": "dev-release",
|
||||
"dist": {
|
||||
"type": "xz",
|
||||
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||
"url": "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
|
@ -786,16 +1045,16 @@
|
|||
},
|
||||
{
|
||||
"name": "heroku/heroku-buildpack-php",
|
||||
"version": "v117",
|
||||
"version": "v120",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/heroku/heroku-buildpack-php.git",
|
||||
"reference": "960199a978308c75926fd9bb4775f7113bf1d777"
|
||||
"reference": "e0499a7fdffd56f46534a037a6c48d65cef4e645"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/960199a978308c75926fd9bb4775f7113bf1d777",
|
||||
"reference": "960199a978308c75926fd9bb4775f7113bf1d777",
|
||||
"url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/e0499a7fdffd56f46534a037a6c48d65cef4e645",
|
||||
"reference": "e0499a7fdffd56f46534a037a6c48d65cef4e645",
|
||||
"shasum": ""
|
||||
},
|
||||
"bin": [
|
||||
|
@ -826,20 +1085,20 @@
|
|||
"nginx",
|
||||
"php"
|
||||
],
|
||||
"time": "2016-12-09T19:37:38+00:00"
|
||||
"time": "2017-02-20T15:05:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.5.5",
|
||||
"version": "1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108"
|
||||
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108",
|
||||
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
|
||||
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -868,7 +1127,7 @@
|
|||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"time": "2016-10-31T17:19:45+00:00"
|
||||
"time": "2017-01-26T22:05:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
|
@ -1018,27 +1277,27 @@
|
|||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.6.2",
|
||||
"version": "v1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
|
||||
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
|
||||
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
|
||||
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
|
||||
"sebastian/comparator": "^1.1",
|
||||
"sebastian/recursion-context": "^1.0|^2.0"
|
||||
"sebastian/comparator": "^1.1|^2.0",
|
||||
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.0",
|
||||
"phpspec/phpspec": "^2.5|^3.2",
|
||||
"phpunit/phpunit": "^4.8 || ^5.6.5"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -1077,39 +1336,39 @@
|
|||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2016-11-21T14:58:47+00:00"
|
||||
"time": "2017-03-02T20:05:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "4.0.4",
|
||||
"version": "4.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a"
|
||||
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a",
|
||||
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69",
|
||||
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"php": "^5.6 || ^7.0",
|
||||
"phpunit/php-file-iterator": "~1.3",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-token-stream": "^1.4.2",
|
||||
"sebastian/code-unit-reverse-lookup": "~1.0",
|
||||
"phpunit/php-file-iterator": "^1.3",
|
||||
"phpunit/php-text-template": "^1.2",
|
||||
"phpunit/php-token-stream": "^1.4.2 || ^2.0",
|
||||
"sebastian/code-unit-reverse-lookup": "^1.0",
|
||||
"sebastian/environment": "^1.3.2 || ^2.0",
|
||||
"sebastian/version": "~1.0|~2.0"
|
||||
"sebastian/version": "^1.0 || ^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-xdebug": ">=2.1.4",
|
||||
"phpunit/phpunit": "^5.4"
|
||||
"ext-xdebug": "^2.1.4",
|
||||
"phpunit/phpunit": "^5.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "*",
|
||||
"ext-xdebug": ">=2.4.0",
|
||||
"ext-xmlwriter": "*"
|
||||
"ext-xdebug": "^2.5.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -1140,7 +1399,7 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2016-12-20T15:22:42+00:00"
|
||||
"time": "2017-03-01T09:12:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -1232,25 +1491,30 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
|
||||
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
|
||||
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
||||
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": "^5.3.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4|~5"
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
|
@ -1272,20 +1536,20 @@
|
|||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2016-05-12T18:03:57+00:00"
|
||||
"time": "2017-02-26T11:10:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "1.4.9",
|
||||
"version": "1.4.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
|
||||
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
|
||||
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
|
||||
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1321,20 +1585,20 @@
|
|||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2016-11-15T14:06:22+00:00"
|
||||
"time": "2017-02-27T10:12:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "5.7.5",
|
||||
"version": "5.7.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe"
|
||||
"reference": "dafc78e2a7d12139b0e97078d1082326bd09363d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe",
|
||||
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/dafc78e2a7d12139b0e97078d1082326bd09363d",
|
||||
"reference": "dafc78e2a7d12139b0e97078d1082326bd09363d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1346,19 +1610,19 @@
|
|||
"myclabs/deep-copy": "~1.3",
|
||||
"php": "^5.6 || ^7.0",
|
||||
"phpspec/prophecy": "^1.6.2",
|
||||
"phpunit/php-code-coverage": "^4.0.3",
|
||||
"phpunit/php-code-coverage": "^4.0.4",
|
||||
"phpunit/php-file-iterator": "~1.4",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-timer": "^1.0.6",
|
||||
"phpunit/phpunit-mock-objects": "^3.2",
|
||||
"sebastian/comparator": "~1.2.2",
|
||||
"sebastian/comparator": "^1.2.4",
|
||||
"sebastian/diff": "~1.2",
|
||||
"sebastian/environment": "^1.3.4 || ^2.0",
|
||||
"sebastian/exporter": "~2.0",
|
||||
"sebastian/global-state": "^1.0 || ^2.0",
|
||||
"sebastian/global-state": "^1.1",
|
||||
"sebastian/object-enumerator": "~2.0",
|
||||
"sebastian/resource-operations": "~1.0",
|
||||
"sebastian/version": "~1.0|~2.0",
|
||||
"sebastian/version": "~1.0.3|~2.0",
|
||||
"symfony/yaml": "~2.1|~3.0"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -1403,7 +1667,7 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2016-12-28T07:18:51+00:00"
|
||||
"time": "2017-03-15T13:02:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
|
@ -1466,62 +1730,34 @@
|
|||
},
|
||||
{
|
||||
"name": "rg3/youtube-dl",
|
||||
"version": "2017.01.10",
|
||||
"version": "2017.03.07",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/rg3/youtube-dl/archive/2017.01.10.zip",
|
||||
"url": "https://github.com/rg3/youtube-dl/archive/2017.03.07.zip",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"type": "library"
|
||||
},
|
||||
{
|
||||
"name": "rudloff/rtmpdump-bin",
|
||||
"version": "2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rudloff/rtmpdump-bin.git",
|
||||
"reference": "133cdd80e3bab66593e88a5276158596383afd97"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Rudloff/rtmpdump-bin/zipball/133cdd80e3bab66593e88a5276158596383afd97",
|
||||
"reference": "133cdd80e3bab66593e88a5276158596383afd97",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"rtmpdump/rtmpdump": "2.3"
|
||||
},
|
||||
"bin": [
|
||||
"rtmpdump"
|
||||
],
|
||||
"type": "library",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-2.0"
|
||||
],
|
||||
"description": "rtmpdump binary for Linux 64 bit",
|
||||
"time": "2016-04-12T19:17:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
|
||||
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
|
||||
"reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
|
||||
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
|
||||
"reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~5"
|
||||
"phpunit/phpunit": "^5.7 || ^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -1546,20 +1782,20 @@
|
|||
],
|
||||
"description": "Looks up which function or method a line of code belongs to",
|
||||
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
|
||||
"time": "2016-02-13T06:45:14+00:00"
|
||||
"time": "2017-03-04T06:30:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f"
|
||||
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
|
||||
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
|
||||
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1610,7 +1846,7 @@
|
|||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"time": "2016-11-19T09:18:40+00:00"
|
||||
"time": "2017-01-29T09:50:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
|
@ -1834,16 +2070,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/object-enumerator",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
|
||||
"reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35"
|
||||
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
|
||||
"reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
|
||||
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1876,7 +2112,7 @@
|
|||
],
|
||||
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
|
||||
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
|
||||
"time": "2016-11-19T07:35:10+00:00"
|
||||
"time": "2017-02-18T15:18:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
|
@ -2155,22 +2391,25 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "f722532b0966e9b6fc631e682143c07b2cf583a0"
|
||||
"reference": "4100f347aff890bc16b0b4b42843b599db257b2d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f722532b0966e9b6fc631e682143c07b2cf583a0",
|
||||
"reference": "f722532b0966e9b6fc631e682143c07b2cf583a0",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/4100f347aff890bc16b0b4b42843b599db257b2d",
|
||||
"reference": "4100f347aff890bc16b0b4b42843b599db257b2d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"twig/twig": "~1.20|~2.0"
|
||||
},
|
||||
|
@ -2214,7 +2453,7 @@
|
|||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2016-12-11T14:34:22+00:00"
|
||||
"time": "2017-02-20T13:45:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
|
|
@ -3,7 +3,6 @@ python: /usr/bin/python
|
|||
params:
|
||||
- --no-playlist
|
||||
- --no-warnings
|
||||
- -f best[protocol^=http]
|
||||
- --playlist-end
|
||||
- 1
|
||||
curl_params:
|
||||
|
@ -12,3 +11,4 @@ avconv: vendor/bin/ffmpeg
|
|||
rtmpdump: vendor/bin/rtmpdump
|
||||
curl: /usr/bin/curl
|
||||
uglyUrls: false
|
||||
stream: false
|
||||
|
|
|
@ -54,6 +54,13 @@ class FrontController
|
|||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* Default youtube-dl format.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultFormat = 'best[protocol^=http]';
|
||||
|
||||
/**
|
||||
* FrontController constructor.
|
||||
*
|
||||
|
@ -68,6 +75,9 @@ class FrontController
|
|||
$session_factory = new \Aura\Session\SessionFactory();
|
||||
$session = $session_factory->newInstance($_COOKIE);
|
||||
$this->sessionSegment = $session->getSegment('Alltube\Controller\FrontController');
|
||||
if ($this->config->stream) {
|
||||
$this->defaultFormat = 'best';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,10 +86,11 @@ class FrontController
|
|||
* @param Request $request PSR-7 request
|
||||
* @param Response $response PSR-7 response
|
||||
*
|
||||
* @return void
|
||||
* @return Response HTTP response
|
||||
*/
|
||||
public function index(Request $request, Response $response)
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$this->view->render(
|
||||
$response,
|
||||
'index.tpl',
|
||||
|
@ -88,8 +99,12 @@ class FrontController
|
|||
'uglyUrls' => $this->config->uglyUrls,
|
||||
'class' => 'index',
|
||||
'description' => 'Easily download videos from Youtube, Dailymotion, Vimeo and other websites.',
|
||||
'domain' => $uri->getScheme().'://'.$uri->getAuthority(),
|
||||
'canonical' => $this->getCanonicalUrl($request),
|
||||
]
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +113,7 @@ class FrontController
|
|||
* @param Request $request PSR-7 request
|
||||
* @param Response $response PSR-7 response
|
||||
*
|
||||
* @return void
|
||||
* @return Response HTTP response
|
||||
*/
|
||||
public function extractors(Request $request, Response $response)
|
||||
{
|
||||
|
@ -111,8 +126,11 @@ class FrontController
|
|||
'title' => 'Supported websites',
|
||||
'description' => 'List of all supported websites from which Alltube Download '.
|
||||
'can extract video or audio files',
|
||||
'canonical' => $this->getCanonicalUrl($request),
|
||||
]
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,8 +150,89 @@ class FrontController
|
|||
'class' => 'password',
|
||||
'title' => 'Password prompt',
|
||||
'description' => 'You need a password in order to download this video with Alltube Download',
|
||||
'canonical' => $this->getCanonicalUrl($request),
|
||||
]
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the converted MP3 file.
|
||||
*
|
||||
* @param Request $request PSR-7 request
|
||||
* @param Response $response PSR-7 response
|
||||
* @param array $params GET query parameters
|
||||
* @param string $password Video password
|
||||
*
|
||||
* @return Response HTTP response
|
||||
*/
|
||||
private function getAudioResponse(Request $request, Response $response, array $params, $password = null)
|
||||
{
|
||||
try {
|
||||
if ($this->config->stream) {
|
||||
return $this->getStream($params['url'], 'mp3', $response, $request, $password);
|
||||
} else {
|
||||
$url = $this->download->getURL($params['url'], 'mp3[protocol^=http]', $password);
|
||||
|
||||
return $response->withRedirect($url);
|
||||
}
|
||||
} catch (PasswordException $e) {
|
||||
return $this->password($request, $response);
|
||||
} catch (\Exception $e) {
|
||||
$response = $response->withHeader(
|
||||
'Content-Disposition',
|
||||
'attachment; filename="'.
|
||||
$this->download->getAudioFilename($params['url'], 'bestaudio/best', $password).'"'
|
||||
);
|
||||
$response = $response->withHeader('Content-Type', 'audio/mpeg');
|
||||
|
||||
if ($request->isGet() || $request->isPost()) {
|
||||
$process = $this->download->getAudioStream($params['url'], 'bestaudio/best', $password);
|
||||
$response = $response->withBody(new Stream($process));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the video description page.
|
||||
*
|
||||
* @param Request $request PSR-7 request
|
||||
* @param Response $response PSR-7 response
|
||||
* @param array $params GET query parameters
|
||||
* @param string $password Video password
|
||||
*
|
||||
* @return Response HTTP response
|
||||
*/
|
||||
private function getVideoResponse(Request $request, Response $response, array $params, $password = null)
|
||||
{
|
||||
try {
|
||||
$video = $this->download->getJSON($params['url'], $this->defaultFormat, $password);
|
||||
} catch (PasswordException $e) {
|
||||
return $this->password($request, $response);
|
||||
}
|
||||
if ($this->config->stream) {
|
||||
$protocol = '';
|
||||
} else {
|
||||
$protocol = '[protocol^=http]';
|
||||
}
|
||||
$this->view->render(
|
||||
$response,
|
||||
'video.tpl',
|
||||
[
|
||||
'video' => $video,
|
||||
'class' => 'video',
|
||||
'title' => $video->title,
|
||||
'description' => 'Download "'.$video->title.'" from '.$video->extractor_key,
|
||||
'protocol' => $protocol,
|
||||
'config' => $this->config,
|
||||
'canonical' => $this->getCanonicalUrl($request),
|
||||
]
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,43 +252,9 @@ class FrontController
|
|||
$this->sessionSegment->setFlash($params['url'], $password);
|
||||
}
|
||||
if (isset($params['audio'])) {
|
||||
try {
|
||||
$url = $this->download->getURL($params['url'], 'mp3[protocol^=http]', $password);
|
||||
|
||||
return $response->withRedirect($url);
|
||||
} catch (PasswordException $e) {
|
||||
return $this->password($request, $response);
|
||||
} catch (\Exception $e) {
|
||||
$response = $response->withHeader(
|
||||
'Content-Disposition',
|
||||
'attachment; filename="'.
|
||||
$this->download->getAudioFilename($params['url'], 'bestaudio/best', $password).'"'
|
||||
);
|
||||
$response = $response->withHeader('Content-Type', 'audio/mpeg');
|
||||
|
||||
if ($request->isGet() || $request->isPost()) {
|
||||
$process = $this->download->getAudioStream($params['url'], 'bestaudio/best', $password);
|
||||
$response = $response->withBody(new Stream($process));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
return $this->getAudioResponse($request, $response, $params, $password);
|
||||
} else {
|
||||
try {
|
||||
$video = $this->download->getJSON($params['url'], null, $password);
|
||||
} catch (PasswordException $e) {
|
||||
return $this->password($request, $response);
|
||||
}
|
||||
$this->view->render(
|
||||
$response,
|
||||
'video.tpl',
|
||||
[
|
||||
'video' => $video,
|
||||
'class' => 'video',
|
||||
'title' => $video->title,
|
||||
'description' => 'Download "'.$video->title.'" from '.$video->extractor_key,
|
||||
]
|
||||
);
|
||||
return $this->getVideoResponse($request, $response, $params, $password);
|
||||
}
|
||||
} else {
|
||||
return $response->withRedirect($this->container->get('router')->pathFor('index'));
|
||||
|
@ -211,15 +276,50 @@ class FrontController
|
|||
$response,
|
||||
'error.tpl',
|
||||
[
|
||||
'errors' => $exception->getMessage(),
|
||||
'class' => 'video',
|
||||
'title' => 'Error',
|
||||
'errors' => $exception->getMessage(),
|
||||
'class' => 'video',
|
||||
'title' => 'Error',
|
||||
'canonical' => $this->getCanonicalUrl($request),
|
||||
]
|
||||
);
|
||||
|
||||
return $response->withStatus(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a video/audio stream piped through the server.
|
||||
*
|
||||
* @param string $url URL of the video
|
||||
* @param string $format Requested format
|
||||
* @param Response $response PSR-7 response
|
||||
* @param Request $request PSR-7 request
|
||||
* @param string $password Video password
|
||||
*
|
||||
* @return Response HTTP response
|
||||
*/
|
||||
private function getStream($url, $format, $response, $request, $password = null)
|
||||
{
|
||||
$video = $this->download->getJSON($url, $format, $password);
|
||||
if ($video->protocol == 'm3u8') {
|
||||
$stream = $this->download->getM3uStream($video);
|
||||
$response = $response->withHeader('Content-Type', 'video/'.$video->ext);
|
||||
if ($request->isGet()) {
|
||||
$response = $response->withBody(new Stream($stream));
|
||||
}
|
||||
} else {
|
||||
$client = new \GuzzleHttp\Client();
|
||||
$stream = $client->request('GET', $video->url, ['stream' => true]);
|
||||
$response = $response->withHeader('Content-Type', $stream->getHeader('Content-Type'));
|
||||
$response = $response->withHeader('Content-Length', $stream->getHeader('Content-Length'));
|
||||
if ($request->isGet()) {
|
||||
$response = $response->withBody($stream->getBody());
|
||||
}
|
||||
}
|
||||
$response = $response->withHeader('Content-Disposition', 'attachment; filename="'.$video->_filename.'"');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to video file.
|
||||
*
|
||||
|
@ -231,15 +331,30 @@ class FrontController
|
|||
public function redirect(Request $request, Response $response)
|
||||
{
|
||||
$params = $request->getQueryParams();
|
||||
if (isset($params['format'])) {
|
||||
$format = $params['format'];
|
||||
} else {
|
||||
$format = $this->defaultFormat;
|
||||
}
|
||||
if (isset($params['url'])) {
|
||||
try {
|
||||
$url = $this->download->getURL(
|
||||
$params['url'],
|
||||
$request->getParam('format'),
|
||||
$this->sessionSegment->getFlash($params['url'])
|
||||
);
|
||||
if ($this->config->stream) {
|
||||
return $this->getStream(
|
||||
$params['url'],
|
||||
$format,
|
||||
$response,
|
||||
$request,
|
||||
$this->sessionSegment->getFlash($params['url'])
|
||||
);
|
||||
} else {
|
||||
$url = $this->download->getURL(
|
||||
$params['url'],
|
||||
$format,
|
||||
$this->sessionSegment->getFlash($params['url'])
|
||||
);
|
||||
|
||||
return $response->withRedirect($url);
|
||||
return $response->withRedirect($url);
|
||||
}
|
||||
} catch (PasswordException $e) {
|
||||
return $response->withRedirect(
|
||||
$this->container->get('router')->pathFor('video').'?url='.urlencode($params['url'])
|
||||
|
@ -247,32 +362,35 @@ class FrontController
|
|||
} catch (\Exception $e) {
|
||||
$response->getBody()->write($e->getMessage());
|
||||
|
||||
return $response->withHeader('Content-Type', 'text/plain');
|
||||
return $response->withHeader('Content-Type', 'text/plain')->withStatus(500);
|
||||
}
|
||||
} else {
|
||||
return $response->withRedirect($this->container->get('router')->pathFor('index'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output JSON info about the video.
|
||||
* Generate the canonical URL of the current page.
|
||||
*
|
||||
* @param Request $request PSR-7 request
|
||||
* @param Response $response PSR-7 response
|
||||
* @param Request $request PSR-7 Request
|
||||
*
|
||||
* @return Response HTTP response
|
||||
* @return string URL
|
||||
*/
|
||||
public function json(Request $request, Response $response)
|
||||
private function getCanonicalUrl(Request $request)
|
||||
{
|
||||
$params = $request->getQueryParams();
|
||||
if (isset($params['url'])) {
|
||||
try {
|
||||
$video = $this->download->getJSON($params['url']);
|
||||
$uri = $request->getUri();
|
||||
$return = 'https://alltubedownload.net/';
|
||||
|
||||
return $response->withJson($video);
|
||||
} catch (\Exception $e) {
|
||||
return $response->withJson(
|
||||
['success' => false, 'error' => $e->getMessage()]
|
||||
);
|
||||
}
|
||||
$path = $uri->getPath();
|
||||
if ($path != '/') {
|
||||
$return .= $path;
|
||||
}
|
||||
|
||||
$query = $uri->getQuery();
|
||||
if (!empty($query)) {
|
||||
$return .= '?'.$query;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,4 @@ $app->get(
|
|||
'/redirect',
|
||||
[$controller, 'redirect']
|
||||
)->setName('redirect');
|
||||
$app->get(
|
||||
'/json',
|
||||
[$controller, 'json']
|
||||
);
|
||||
$app->run();
|
||||
|
|
10
package.json
10
package.json
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"name": "alltube",
|
||||
"description": "HTML GUI for youtube-dl",
|
||||
"version": "0.7.2-beta",
|
||||
"version": "0.7.2-beta2",
|
||||
"author": "Pierre Rudloff",
|
||||
"bugs": "https://github.com/Rudloff/alltube/issues",
|
||||
"dependencies": {
|
||||
"bower": "~1.8.0",
|
||||
"grunt": "~1.0.1",
|
||||
"grunt-contrib-cssmin": "~1.0.0",
|
||||
"grunt-contrib-uglify": "~2.0.0"
|
||||
"grunt-contrib-cssmin": "~2.0.0",
|
||||
"grunt-contrib-uglify": "~2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt-contrib-compress": "~1.3.0",
|
||||
"grunt-contrib-compress": "~1.4.1",
|
||||
"grunt-contrib-watch": "~1.0.0",
|
||||
"grunt-fixpack": "~0.1.0",
|
||||
"grunt-githash": "~0.1.3",
|
||||
|
@ -27,7 +27,7 @@
|
|||
"homepage": "https://www.alltubedownload.net/",
|
||||
"keywords": [
|
||||
"alltube",
|
||||
"dowload",
|
||||
"download",
|
||||
"video",
|
||||
"youtube"
|
||||
],
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<phpunit bootstrap="vendor/autoload.php">
|
||||
<phpunit bootstrap="tests/bootstrap.php">
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>classes/</directory>
|
||||
<directory>controllers/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<testsuites>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{/if}
|
||||
<link rel="stylesheet" href="{base_url|noscheme}/dist/main.css" />
|
||||
<title>AllTube Download{if isset($title)} - {$title|escape}{/if}</title>
|
||||
<link rel="canonical" href="//{$smarty.server.HTTP_HOST|cat:$smarty.server.REQUEST_URI|replace:{base_url|noscheme}:'http://www.alltubedownload.net'}" />
|
||||
<link rel="canonical" href="{$canonical}" />
|
||||
<link rel="icon" href="{base_url|noscheme}/img/favicon.png" />
|
||||
<meta property="og:title" content="AllTube Download{if isset($title)} - {$title|escape}{/if}" />
|
||||
<meta property="og:image" content="{base_url}/img/logo.png" />
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<input class="URLinput" type="url" name="url" id="url"
|
||||
required autofocus placeholder="http://example.com/video" />
|
||||
</span>
|
||||
{if uglyUrls}
|
||||
{if $uglyUrls}
|
||||
<input type="hidden" name="page" value="video" />
|
||||
{/if}
|
||||
<input class="downloadBtn" type="submit" value="Download" /><br/>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<a class="combatiblelink" href="{path_for name="extractors"}">See all supported websites</a>
|
||||
<div id="bookmarklet" class="bookmarklet_wrapper">
|
||||
<p> Drag this to your bookmarks bar: </p>
|
||||
<a class="bookmarklet" href="javascript:window.location='{base_url|noscheme}{path_for name='video'}?url='+encodeURIComponent(location.href);">Bookmarklet</a>
|
||||
<a class="bookmarklet" href="javascript:window.location='{$domain}{path_for name='video'}?url='+encodeURIComponent(location.href);">Bookmarklet</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -29,18 +29,18 @@
|
|||
{/if}
|
||||
<select name="format" id="format" class="formats monospace">
|
||||
<optgroup label="Generic formats">
|
||||
<option value="best[protocol^=http]">
|
||||
<option value="best{$protocol}">
|
||||
{strip}
|
||||
Best ({$video->ext})
|
||||
{/strip}
|
||||
</option>
|
||||
<option value="worst[protocol^=http]">
|
||||
<option value="worst{$protocol}">
|
||||
Worst
|
||||
</option>
|
||||
</optgroup>
|
||||
<optgroup label="Detailed formats" class="monospace">
|
||||
{foreach $video->formats as $format}
|
||||
{if $format->protocol|in_array:array('http', 'https')}
|
||||
{if $config->stream || $format->protocol|in_array:array('http', 'https')}
|
||||
{strip}
|
||||
<option value="{$format->format_id}">
|
||||
{$format->ext}
|
||||
|
@ -80,7 +80,7 @@
|
|||
<input class="downloadBtn" type="submit" value="Download" /><br/>
|
||||
</form>
|
||||
{else}
|
||||
<input type="hidden" name="format" value="best[protocol^=http]" />
|
||||
<input type="hidden" name="format" value="best{$protocol}" />
|
||||
<a class="downloadBtn"
|
||||
href="{$video->url|escape}">Download</a><br/>
|
||||
{/if}
|
||||
|
|
370
tests/FrontControllerTest.php
Normal file
370
tests/FrontControllerTest.php
Normal file
|
@ -0,0 +1,370 @@
|
|||
<?php
|
||||
/**
|
||||
* FrontControllerTest class.
|
||||
*/
|
||||
|
||||
namespace Alltube\Test;
|
||||
|
||||
use Alltube\Config;
|
||||
use Alltube\Controller\FrontController;
|
||||
use Slim\Container;
|
||||
use Slim\Http\Environment;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
/**
|
||||
* Unit tests for the FrontController class.
|
||||
*/
|
||||
class FrontControllerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Slim dependency container.
|
||||
*
|
||||
* @var Container
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* Mock HTTP request.
|
||||
*
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* Mock HTTP response.
|
||||
*
|
||||
* @var Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* FrontController instance used in tests.
|
||||
*
|
||||
* @var FrontController
|
||||
*/
|
||||
private $controller;
|
||||
|
||||
/**
|
||||
* Prepare tests.
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->container = new Container();
|
||||
$this->request = Request::createFromEnvironment(Environment::mock());
|
||||
$this->response = new Response();
|
||||
$this->container['view'] = function ($c) {
|
||||
$view = new \Slim\Views\Smarty(__DIR__.'/../templates/');
|
||||
|
||||
$smartyPlugins = new \Slim\Views\SmartyPlugins($c['router'], $this->request->getUri());
|
||||
$view->registerPlugin('function', 'path_for', [$smartyPlugins, 'pathFor']);
|
||||
$view->registerPlugin('function', 'base_url', [$smartyPlugins, 'baseUrl']);
|
||||
|
||||
$view->registerPlugin('modifier', 'noscheme', 'Smarty_Modifier_noscheme');
|
||||
|
||||
return $view;
|
||||
};
|
||||
$this->controller = new FrontController($this->container);
|
||||
$this->container['router']->map(['GET'], '/', [$this->controller, 'index'])
|
||||
->setName('index');
|
||||
$this->container['router']->map(['GET'], '/video', [$this->controller, 'video'])
|
||||
->setName('video');
|
||||
$this->container['router']->map(['GET'], '/extractors', [$this->controller, 'extractors'])
|
||||
->setName('extractors');
|
||||
$this->container['router']->map(['GET'], '/redirect', [$this->controller, 'redirect'])
|
||||
->setName('redirect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy properties after test.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
Config::destroyInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the constructor with streams enabled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConstructorWithStream()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->stream = true;
|
||||
$controller = new FrontController($this->container);
|
||||
$this->assertInstanceOf(FrontController::class, $controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the index() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIndex()
|
||||
{
|
||||
$result = $this->controller->index($this->request, $this->response);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the index() function with a custom URI.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIndexWithCustomUri()
|
||||
{
|
||||
$result = $this->controller->index(
|
||||
Request::createFromEnvironment(
|
||||
Environment::mock(['REQUEST_URI'=>'/foo', 'QUERY_STRING'=>'foo=bar'])
|
||||
),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the extractors() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExtractors()
|
||||
{
|
||||
$result = $this->controller->extractors($this->request, $this->response);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the password() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPassword()
|
||||
{
|
||||
$result = $this->controller->password($this->request, $this->response);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function without the url parameter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithoutUrl()
|
||||
{
|
||||
$result = $this->controller->video($this->request, $this->response);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideo()
|
||||
{
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function with audio conversion.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithAudio()
|
||||
{
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'audio'=>true]),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function with audio enabled and an URL that doesn't need to be converted.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithUnconvertedAudio()
|
||||
{
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(
|
||||
['url' => 'https://soundcloud.com/verwandlungskuenstler/metamorphosis-by-franz-kafka-1',
|
||||
'audio'=> true, ]
|
||||
),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function with a password.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithPassword()
|
||||
{
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'http://vimeo.com/68375962'])
|
||||
->withParsedBody(['password'=>'youtube-dl']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function with a missing password.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithMissingPassword()
|
||||
{
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'http://vimeo.com/68375962']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'http://vimeo.com/68375962', 'audio'=>true]),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the video() function with streams enabled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVideoWithStream()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->stream = true;
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
$result = $this->controller->video(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'audio'=>true]),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the error() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testError()
|
||||
{
|
||||
$result = $this->controller->error($this->request, $this->response, new \Exception('foo'));
|
||||
$this->assertTrue($result->isServerError());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function without the URL parameter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithoutUrl()
|
||||
{
|
||||
$result = $this->controller->redirect($this->request, $this->response);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirect()
|
||||
{
|
||||
$result = $this->controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function with a specific format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithFormat()
|
||||
{
|
||||
$result = $this->controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'format'=>'worst']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function with streams enabled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithStream()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->stream = true;
|
||||
$result = $this->controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'https://www.youtube.com/watch?v=M7IpKCZ47pU']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function with an M3U stream.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithM3uStream()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->stream = true;
|
||||
//We need to create a new controller instance in order to apply the custom config
|
||||
$controller = new FrontController($this->container);
|
||||
$result = $controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'https://twitter.com/verge/status/813055465324056576/video/1']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function with a missing password.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithMissingPassword()
|
||||
{
|
||||
$result = $this->controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'http://vimeo.com/68375962']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the redirect() function with an error.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRedirectWithError()
|
||||
{
|
||||
$result = $this->controller->redirect(
|
||||
$this->request->withQueryParams(['url'=>'http://example.com/foo']),
|
||||
$this->response
|
||||
);
|
||||
$this->assertTrue($result->isServerError());
|
||||
}
|
||||
}
|
|
@ -7,10 +7,7 @@ namespace Alltube\Test;
|
|||
|
||||
use Alltube\UglyRouter;
|
||||
use Slim\Http\Environment;
|
||||
use Slim\Http\Headers;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Stream;
|
||||
use Slim\Http\Uri;
|
||||
|
||||
/**
|
||||
* Unit tests for the UglyRouter class.
|
||||
|
@ -43,13 +40,13 @@ class UglyRouterTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(
|
||||
[1, 'route0', []],
|
||||
$this->router->dispatch(
|
||||
new Request(
|
||||
'GET',
|
||||
Uri::createFromString('http://example.com/?page=foo'),
|
||||
Headers::createFromEnvironment(new Environment()),
|
||||
[],
|
||||
[],
|
||||
new Stream(fopen('php://temp', 'r'))
|
||||
Request::createFromEnvironment(
|
||||
Environment::mock(
|
||||
[
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'QUERY_STRING' => 'page=foo',
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -146,7 +146,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
return [
|
||||
[
|
||||
'https://www.youtube.com/watch?v=M7IpKCZ47pU', null,
|
||||
'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'best[protocol^=http]',
|
||||
"It's Not Me, It's You - Hearts Under Fire-M7IpKCZ47pU",
|
||||
'mp4',
|
||||
'googlevideo.com',
|
||||
|
@ -159,7 +159,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
'googlevideo.com',
|
||||
],
|
||||
[
|
||||
'https://vimeo.com/24195442', null,
|
||||
'https://vimeo.com/24195442', 'best[protocol^=http]',
|
||||
'Carving the Mountains-24195442',
|
||||
'mp4',
|
||||
'vimeocdn.com',
|
||||
|
@ -179,6 +179,23 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides M3U8 URLs for tests.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function m3uUrlProvider()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'https://twitter.com/verge/status/813055465324056576/video/1', 'best',
|
||||
'The Verge - This tiny origami robot can self-fold and complete tasks-813055465324056576',
|
||||
'mp4',
|
||||
'video.twimg.com',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides incorrect URLs for tests.
|
||||
*
|
||||
|
@ -199,6 +216,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
*
|
||||
* @return void
|
||||
* @dataProvider URLProvider
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetJSON($url, $format)
|
||||
{
|
||||
|
@ -207,6 +225,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertObjectHasAttribute('url', $info);
|
||||
$this->assertObjectHasAttribute('ext', $info);
|
||||
$this->assertObjectHasAttribute('title', $info);
|
||||
$this->assertObjectHasAttribute('extractor_key', $info);
|
||||
$this->assertObjectHasAttribute('formats', $info);
|
||||
$this->assertObjectHasAttribute('_filename', $info);
|
||||
}
|
||||
|
@ -222,7 +241,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testGetJSONError($url)
|
||||
{
|
||||
$videoURL = $this->download->getJSON($url);
|
||||
$this->download->getJSON($url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,6 +254,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
*
|
||||
* @return void
|
||||
* @dataProvider urlProvider
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetFilename($url, $format, $filename, $extension)
|
||||
{
|
||||
|
@ -259,14 +279,13 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
/**
|
||||
* Test getAudioFilename function.
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param string $format Format
|
||||
* @param string $filename Filename
|
||||
* @param string $domain Domain
|
||||
* @param string $audioFilename MP3 audio file name
|
||||
* @param string $url URL
|
||||
* @param string $format Format
|
||||
* @param string $filename Filename
|
||||
*
|
||||
* @return void
|
||||
* @dataProvider urlProvider
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetAudioFilename($url, $format, $filename)
|
||||
{
|
||||
|
@ -302,7 +321,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testGetAudioStreamAvconvError($url, $format)
|
||||
{
|
||||
$config = \Alltube\Config::getInstance();
|
||||
$config = Config::getInstance();
|
||||
$config->avconv = 'foobar';
|
||||
$this->download->getAudioStream($url, $format);
|
||||
}
|
||||
|
@ -319,7 +338,7 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public function testGetAudioStreamCurlError($url, $format)
|
||||
{
|
||||
$config = \Alltube\Config::getInstance();
|
||||
$config = Config::getInstance();
|
||||
$config->curl = 'foobar';
|
||||
$config->rtmpdump = 'foobar';
|
||||
$this->download->getAudioStream($url, $format);
|
||||
|
@ -328,11 +347,50 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
|||
/**
|
||||
* Test getAudioStream function with a M3U8 file.
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param string $format Format
|
||||
*
|
||||
* @return void
|
||||
* @expectedException Exception
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetAudioStreamM3uError()
|
||||
public function testGetAudioStreamM3uError($url, $format)
|
||||
{
|
||||
$this->download->getAudioStream('https://twitter.com/verge/status/813055465324056576/video/1', 'best');
|
||||
$this->download->getAudioStream($url, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getM3uStream function.
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param string $format Format
|
||||
*
|
||||
* @return void
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetM3uStream($url, $format)
|
||||
{
|
||||
$video = $this->download->getJSON($url, $format);
|
||||
$stream = $this->download->getM3uStream($video);
|
||||
$this->assertInternalType('resource', $stream);
|
||||
$this->assertFalse(feof($stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getM3uStream function without avconv.
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param string $format Format
|
||||
*
|
||||
* @return void
|
||||
* @expectedException Exception
|
||||
* @dataProvider m3uUrlProvider
|
||||
*/
|
||||
public function testGetM3uStreamAvconvError($url, $format)
|
||||
{
|
||||
$config = \Alltube\Config::getInstance();
|
||||
$config->avconv = 'foobar';
|
||||
$video = $this->download->getJSON($url, $format);
|
||||
$this->download->getM3uStream($video);
|
||||
}
|
||||
}
|
||||
|
|
11
tests/bootstrap.php
Normal file
11
tests/bootstrap.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
/**
|
||||
* File used to bootstrap tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Composer autoload.
|
||||
*/
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
session_start();
|
Loading…
Reference in a new issue