Merge branch 'release-0.5.0'
2
.gitignore
vendored
|
@ -6,7 +6,7 @@ vendor/
|
||||||
templates_c/
|
templates_c/
|
||||||
ffmpeg.tar.xz
|
ffmpeg.tar.xz
|
||||||
ffmpeg-*/
|
ffmpeg-*/
|
||||||
alltube-release.zip
|
alltube-*.zip
|
||||||
coverage/
|
coverage/
|
||||||
bower_components/
|
bower_components/
|
||||||
config.yml
|
config.yml
|
||||||
|
|
11
.htaccess
|
@ -1,4 +1,6 @@
|
||||||
AddType application/x-web-app-manifest+json .webapp
|
AddType application/x-web-app-manifest+json .webapp
|
||||||
|
Addtype font/truetype .ttf
|
||||||
|
|
||||||
<ifmodule mod_expires.c>
|
<ifmodule mod_expires.c>
|
||||||
ExpiresActive On
|
ExpiresActive On
|
||||||
ExpiresByType application/javascript "access plus 1 week"
|
ExpiresByType application/javascript "access plus 1 week"
|
||||||
|
@ -6,11 +8,20 @@ AddType application/x-web-app-manifest+json .webapp
|
||||||
ExpiresByType image/png "access plus 1 week"
|
ExpiresByType image/png "access plus 1 week"
|
||||||
ExpiresByType image/jpeg "access plus 1 week"
|
ExpiresByType image/jpeg "access plus 1 week"
|
||||||
ExpiresByType image/svg+xml "access plus 1 week"
|
ExpiresByType image/svg+xml "access plus 1 week"
|
||||||
|
ExpiresByType font/truetype "access plus 1 week"
|
||||||
</ifmodule>
|
</ifmodule>
|
||||||
|
|
||||||
FileETag None
|
FileETag None
|
||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
|
||||||
|
RewriteCond %{HTTP_HOST} ^alltube\.herokuapp\.com$ [NC]
|
||||||
|
RewriteRule ^(.*)$ https://www.alltubedownload.net/$1 [R=301,L]
|
||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteRule ^ index.php [QSA,L]
|
RewriteRule ^ index.php [QSA,L]
|
||||||
|
|
||||||
Redirect permanent /api.php /video
|
Redirect permanent /api.php /video
|
||||||
Redirect permanent /extractors.php /extractors
|
Redirect permanent /extractors.php /extractors
|
||||||
|
|
||||||
|
AddOutputFilterByType DEFLATE text/css text/html application/javascript
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM php:apache
|
FROM php:5.6-apache
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y libicu-dev xz-utils git zlib1g-dev python npm nodejs-legacy
|
RUN apt-get install -y libicu-dev xz-utils git zlib1g-dev python npm nodejs-legacy
|
||||||
RUN docker-php-ext-install mbstring
|
RUN docker-php-ext-install mbstring
|
||||||
|
|
18
Gruntfile.js
|
@ -3,6 +3,11 @@ module.exports = function (grunt) {
|
||||||
'use strict';
|
'use strict';
|
||||||
grunt.initConfig(
|
grunt.initConfig(
|
||||||
{
|
{
|
||||||
|
githash: {
|
||||||
|
main: {
|
||||||
|
options: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
uglify: {
|
uglify: {
|
||||||
combine: {
|
combine: {
|
||||||
files: {
|
files: {
|
||||||
|
@ -28,12 +33,17 @@ module.exports = function (grunt) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
phpcs: {
|
phpcs: {
|
||||||
|
options: {
|
||||||
|
standard: 'PSR2'
|
||||||
|
},
|
||||||
php: {
|
php: {
|
||||||
src: ['*.php', 'classes/*.php', 'controllers/*.php']
|
src: ['*.php', 'classes/*.php', 'controllers/*.php']
|
||||||
},
|
},
|
||||||
tests: {
|
tests: {
|
||||||
src: ['tests/*.php']
|
src: ['tests/*.php']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
jslint: {
|
||||||
js: {
|
js: {
|
||||||
src: ['js/*.js']
|
src: ['js/*.js']
|
||||||
},
|
},
|
||||||
|
@ -49,7 +59,7 @@ module.exports = function (grunt) {
|
||||||
compress: {
|
compress: {
|
||||||
release: {
|
release: {
|
||||||
options: {
|
options: {
|
||||||
archive: 'alltube-release.zip'
|
archive: 'alltube-<%= githash.main.tag %>.zip'
|
||||||
},
|
},
|
||||||
src: ['*.php', '!config.yml', 'dist/**', 'fonts/**', '.htaccess', 'img/**', 'js/**', 'LICENSE', 'README.md', 'robots.txt', 'sitemap.xml', 'templates/**', 'templates_c/', 'vendor/**', 'classes/**', 'controllers/**', 'bower_components/**', '!vendor/ffmpeg/**', '!vendor/bin/ffmpeg']
|
src: ['*.php', '!config.yml', 'dist/**', 'fonts/**', '.htaccess', 'img/**', 'js/**', 'LICENSE', 'README.md', 'robots.txt', 'sitemap.xml', 'templates/**', 'templates_c/', 'vendor/**', 'classes/**', 'controllers/**', 'bower_components/**', '!vendor/ffmpeg/**', '!vendor/bin/ffmpeg']
|
||||||
}
|
}
|
||||||
|
@ -57,15 +67,17 @@ module.exports = function (grunt) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
grunt.loadNpmTasks('grunt-githash');
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
grunt.loadNpmTasks('grunt-phpcs');
|
grunt.loadNpmTasks('grunt-phpcs');
|
||||||
grunt.loadNpmTasks('grunt-phpunit');
|
grunt.loadNpmTasks('grunt-phpunit');
|
||||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||||
|
grunt.loadNpmTasks('grunt-jslint');
|
||||||
|
|
||||||
grunt.registerTask('default', ['uglify', 'cssmin']);
|
grunt.registerTask('default', ['uglify', 'cssmin']);
|
||||||
grunt.registerTask('lint', ['phpcs']);
|
grunt.registerTask('lint', ['phpcs', 'jslint']);
|
||||||
grunt.registerTask('test', ['phpunit']);
|
grunt.registerTask('test', ['phpunit']);
|
||||||
grunt.registerTask('release', ['default', 'compress']);
|
grunt.registerTask('release', ['default', 'githash', 'compress']);
|
||||||
};
|
};
|
||||||
|
|
66
README.md
|
@ -6,6 +6,13 @@ HTML GUI for youtube-dl (http://alltubedownload.net/)
|
||||||
![Screenshot](img/screenshot.png "Alltube GUI screenshot")
|
![Screenshot](img/screenshot.png "Alltube GUI screenshot")
|
||||||
|
|
||||||
##Setup
|
##Setup
|
||||||
|
|
||||||
|
### From a release package
|
||||||
|
You can download the latest release package [here](https://github.com/Rudloff/alltube/releases).
|
||||||
|
|
||||||
|
You just have to unzip it on your server and it should be ready to use.
|
||||||
|
|
||||||
|
### From Git
|
||||||
In order to get AllTube working, you need to use [npm](https://www.npmjs.com/) and [Composer](https://getcomposer.org/):
|
In order to get AllTube working, you need to use [npm](https://www.npmjs.com/) and [Composer](https://getcomposer.org/):
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
|
@ -27,6 +34,61 @@ If you want to use a custom config, you need to create a config file:
|
||||||
|
|
||||||
cp config.example.yml config.yml
|
cp config.example.yml config.yml
|
||||||
|
|
||||||
|
##Web server configuration
|
||||||
|
###Apache
|
||||||
|
You will need the following modules:
|
||||||
|
|
||||||
|
* mod_mime
|
||||||
|
* mod_rewrite
|
||||||
|
|
||||||
|
###Nginx
|
||||||
|
Here is an exemple Nginx configuration:
|
||||||
|
|
||||||
|
server {
|
||||||
|
server_name localhost;
|
||||||
|
listen 443 ssl;
|
||||||
|
|
||||||
|
root /var/www/path/to/alltube;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/alltube.access.log;
|
||||||
|
error_log /var/log/nginx/alltube.error.log;
|
||||||
|
|
||||||
|
types {
|
||||||
|
text/html html htm shtml;
|
||||||
|
text/css css;
|
||||||
|
text/xml xml;
|
||||||
|
application/x-web-app-manifest+json webapp;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deny access to dotfiles
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri /index.php?$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files $uri /index.php?$args;
|
||||||
|
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
fastcgi_intercept_errors off;
|
||||||
|
|
||||||
|
fastcgi_buffer_size 16k;
|
||||||
|
fastcgi_buffers 4 16k;
|
||||||
|
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##License
|
##License
|
||||||
This software is available under the [GNU General Public License](http://www.gnu.org/licenses/gpl.html).
|
This software is available under the [GNU General Public License](http://www.gnu.org/licenses/gpl.html).
|
||||||
|
@ -34,11 +96,11 @@ This software is available under the [GNU General Public License](http://www.gnu
|
||||||
__Please use a different name and logo if you run it on a public server.__
|
__Please use a different name and logo if you run it on a public server.__
|
||||||
|
|
||||||
##Other dependencies
|
##Other dependencies
|
||||||
You need [avconv](https://libav.org/avconv.html) and [rtmpdump](http://rtmpdump.mplayerhq.hu/) in order to enable conversions.
|
You need [avconv](https://libav.org/avconv.html), [rtmpdump](http://rtmpdump.mplayerhq.hu/) and [curl](https://curl.haxx.se/) in order to enable conversions.
|
||||||
If you don't want to enable conversions, you can disable it in *config.yml*.
|
If you don't want to enable conversions, you can disable it in *config.yml*.
|
||||||
|
|
||||||
On Debian-based systems:
|
On Debian-based systems:
|
||||||
|
|
||||||
sudo apt-get install libav-tools rtmpdump
|
sudo apt-get install libav-tools rtmpdump curl
|
||||||
|
|
||||||
You also probably need to edit the *avconv* variable in *config.yml* so that it points to your ffmpeg/avconv binary (*/usr/bin/avconv* on Debian/Ubuntu).
|
You also probably need to edit the *avconv* variable in *config.yml* so that it points to your ffmpeg/avconv binary (*/usr/bin/avconv* on Debian/Ubuntu).
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
namespace Alltube;
|
namespace Alltube;
|
||||||
|
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage config parameters
|
* Class to manage config parameters
|
||||||
*
|
*
|
||||||
|
@ -23,16 +25,17 @@ use Symfony\Component\Yaml\Yaml;
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
Class Config
|
class Config
|
||||||
{
|
{
|
||||||
private static $_instance;
|
private static $instance;
|
||||||
|
|
||||||
public $youtubedl = 'vendor/rg3/youtube-dl/youtube_dl/__main__.py';
|
public $youtubedl = 'vendor/rg3/youtube-dl/youtube_dl/__main__.py';
|
||||||
public $python = '/usr/bin/python';
|
public $python = '/usr/bin/python';
|
||||||
public $params = '--no-playlist --no-warnings -f best';
|
public $params = array('--no-playlist', '--no-warnings', '-f best[protocol^=http]', '--playlist-end', 1);
|
||||||
public $convert = false;
|
public $convert = false;
|
||||||
public $avconv = 'vendor/bin/ffmpeg';
|
public $avconv = 'vendor/bin/ffmpeg';
|
||||||
public $curl_params = '';
|
public $rtmpdump = 'vendor/bin/rtmpdump';
|
||||||
|
public $curl_params = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config constructor
|
* Config constructor
|
||||||
|
@ -43,7 +46,7 @@ Class Config
|
||||||
if (is_file($yamlfile)) {
|
if (is_file($yamlfile)) {
|
||||||
$yaml = Yaml::parse(file_get_contents($yamlfile));
|
$yaml = Yaml::parse(file_get_contents($yamlfile));
|
||||||
if (isset($yaml) && is_array($yaml)) {
|
if (isset($yaml) && is_array($yaml)) {
|
||||||
foreach ($yaml as $param=>$value) {
|
foreach ($yaml as $param => $value) {
|
||||||
if (isset($this->$param)) {
|
if (isset($this->$param)) {
|
||||||
$this->$param = $value;
|
$this->$param = $value;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +65,9 @@ Class Config
|
||||||
*/
|
*/
|
||||||
public static function getInstance()
|
public static function getInstance()
|
||||||
{
|
{
|
||||||
if (is_null(self::$_instance)) {
|
if (is_null(self::$instance)) {
|
||||||
self::$_instance = new Config();
|
self::$instance = new Config();
|
||||||
}
|
}
|
||||||
return self::$_instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
namespace Alltube;
|
namespace Alltube;
|
||||||
|
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
use Symfony\Component\Process\ProcessBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class
|
* Main class
|
||||||
*
|
*
|
||||||
|
@ -22,25 +26,18 @@ namespace Alltube;
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
Class VideoDownload
|
class VideoDownload
|
||||||
{
|
{
|
||||||
/**
|
public function __construct()
|
||||||
* Get the user agent used youtube-dl
|
|
||||||
*
|
|
||||||
* @return string UA
|
|
||||||
* */
|
|
||||||
static function getUA()
|
|
||||||
{
|
{
|
||||||
$config = Config::getInstance();
|
$this->config = Config::getInstance();
|
||||||
$cmd = escapeshellcmd(
|
$this->procBuilder = new ProcessBuilder();
|
||||||
$config->python.' '.escapeshellarg($config->youtubedl).
|
$this->procBuilder->setPrefix(
|
||||||
' '.$config->params
|
array_merge(
|
||||||
|
array($this->config->python, $this->config->youtubedl),
|
||||||
|
$this->config->params
|
||||||
|
)
|
||||||
);
|
);
|
||||||
exec(
|
|
||||||
$cmd.' --dump-user-agent',
|
|
||||||
$version
|
|
||||||
);
|
|
||||||
return $version[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,44 +45,16 @@ Class VideoDownload
|
||||||
*
|
*
|
||||||
* @return array Extractors
|
* @return array Extractors
|
||||||
* */
|
* */
|
||||||
static function listExtractors()
|
public function listExtractors()
|
||||||
{
|
{
|
||||||
$config = Config::getInstance();
|
$this->procBuilder->setArguments(
|
||||||
$cmd = escapeshellcmd(
|
array(
|
||||||
$config->python.' '.escapeshellarg($config->youtubedl).
|
'--list-extractors'
|
||||||
' '.$config->params
|
)
|
||||||
);
|
);
|
||||||
exec(
|
$process = $this->procBuilder->getProcess();
|
||||||
$cmd.' --list-extractors',
|
$process->run();
|
||||||
$extractors
|
return explode(PHP_EOL, $process->getOutput());
|
||||||
);
|
|
||||||
return $extractors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get filename of video
|
|
||||||
*
|
|
||||||
* @param string $url URL of page
|
|
||||||
* @param string $format Format to use for the video
|
|
||||||
*
|
|
||||||
* @return string Filename
|
|
||||||
* */
|
|
||||||
static function getFilename($url, $format=null)
|
|
||||||
{
|
|
||||||
$config = Config::getInstance();
|
|
||||||
$cmd = escapeshellcmd(
|
|
||||||
$config->python.' '.escapeshellarg($config->youtubedl).
|
|
||||||
' '.$config->params
|
|
||||||
);
|
|
||||||
if (isset($format)) {
|
|
||||||
$cmd .= ' -f '.escapeshellarg($format);
|
|
||||||
}
|
|
||||||
$cmd .=' --get-filename '.escapeshellarg($url)." 2>&1";
|
|
||||||
exec(
|
|
||||||
$cmd,
|
|
||||||
$filename
|
|
||||||
);
|
|
||||||
return end($filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,26 +63,25 @@ Class VideoDownload
|
||||||
* @param string $url URL of page
|
* @param string $url URL of page
|
||||||
* @param string $format Format to use for the video
|
* @param string $format Format to use for the video
|
||||||
*
|
*
|
||||||
* @return string JSON
|
* @return object Decoded JSON
|
||||||
* */
|
* */
|
||||||
static function getJSON($url, $format=null)
|
public function getJSON($url, $format = null)
|
||||||
{
|
{
|
||||||
$config = Config::getInstance();
|
$this->procBuilder->setArguments(
|
||||||
$cmd = escapeshellcmd(
|
array(
|
||||||
$config->python.' '.escapeshellarg($config->youtubedl).
|
'--dump-json',
|
||||||
' '.$config->params
|
$url
|
||||||
|
)
|
||||||
);
|
);
|
||||||
if (isset($format)) {
|
if (isset($format)) {
|
||||||
$cmd .= ' -f '.escapeshellarg($format);
|
$this->procBuilder->add('-f '.$format);
|
||||||
}
|
}
|
||||||
$cmd .=' --dump-json '.escapeshellarg($url)." 2>&1";
|
$process = $this->procBuilder->getProcess();
|
||||||
exec(
|
$process->run();
|
||||||
$cmd, $result, $code
|
if (!$process->isSuccessful()) {
|
||||||
);
|
throw new \Exception($process->getErrorOutput());
|
||||||
if ($code>0) {
|
|
||||||
throw new \Exception(implode(PHP_EOL, $result));
|
|
||||||
} else {
|
} else {
|
||||||
return json_decode($result[0]);
|
return json_decode($process->getOutput());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,24 +93,23 @@ Class VideoDownload
|
||||||
*
|
*
|
||||||
* @return string URL of video
|
* @return string URL of video
|
||||||
* */
|
* */
|
||||||
static function getURL($url, $format=null)
|
public function getURL($url, $format = null)
|
||||||
{
|
{
|
||||||
$config = Config::getInstance();
|
$this->procBuilder->setArguments(
|
||||||
$cmd = escapeshellcmd(
|
array(
|
||||||
$config->python.' '.escapeshellarg($config->youtubedl).
|
'--get-url',
|
||||||
' '.$config->params
|
$url
|
||||||
|
)
|
||||||
);
|
);
|
||||||
if (isset($format)) {
|
if (isset($format)) {
|
||||||
$cmd .= ' -f '.escapeshellarg($format);
|
$this->procBuilder->add('-f '.$format);
|
||||||
}
|
}
|
||||||
$cmd .=' -g '.escapeshellarg($url)." 2>&1";
|
$process = $this->procBuilder->getProcess();
|
||||||
exec(
|
$process->run();
|
||||||
$cmd, $result, $code
|
if (!$process->isSuccessful()) {
|
||||||
);
|
throw new \Exception($process->getErrorOutput());
|
||||||
if ($code>0) {
|
|
||||||
throw new \Exception(implode(PHP_EOL, $result));
|
|
||||||
} else {
|
} else {
|
||||||
return array('success'=>true, 'url'=>end($result));
|
return $process->getOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,18 @@
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"smarty/smarty": "~3.1.29",
|
"smarty/smarty": "~3.1.29",
|
||||||
"rg3/youtube-dl": "2016.03.14",
|
"rg3/youtube-dl": "~2016.07.26",
|
||||||
"slim/slim": "~2.6.2",
|
"slim/slim": "~3.5.0",
|
||||||
"slim/views": "~0.1.3",
|
"mathmarques/smarty-view": "~1.1.0",
|
||||||
|
"symfony/yaml": "~3.1.0",
|
||||||
|
"symfony/process": "~3.1.0",
|
||||||
|
"ptachoire/process-builder-chain": "~1.2.0",
|
||||||
|
"ffmpeg/ffmpeg": "dev-release",
|
||||||
"rudloff/smarty-plugin-noscheme": "~0.1.0",
|
"rudloff/smarty-plugin-noscheme": "~0.1.0",
|
||||||
"symfony/yaml": "~3.0.0",
|
"rudloff/rtmpdump-bin": "~2.3"
|
||||||
"ffmpeg/ffmpeg": "~2.8.2"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "~3.0.0"
|
"symfony/var-dumper": "~3.1.0"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"paas": {
|
"paas": {
|
||||||
|
@ -27,18 +30,18 @@
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": {
|
"package": {
|
||||||
"name": "rg3/youtube-dl",
|
"name": "rg3/youtube-dl",
|
||||||
"version": "2016.03.14",
|
"version": "2016.07.26",
|
||||||
"source": {
|
"source": {
|
||||||
"url": "https://github.com/rg3/youtube-dl.git",
|
"url": "https://github.com/rg3/youtube-dl.git",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"reference": "2016.03.14"
|
"reference": "2016.07.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": {
|
"package": {
|
||||||
"name": "ffmpeg/ffmpeg",
|
"name": "ffmpeg/ffmpeg",
|
||||||
"version": "2.8.4",
|
"version": "dev-release",
|
||||||
"dist": {
|
"dist": {
|
||||||
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||||
"type": "xz"
|
"type": "xz"
|
||||||
|
|
465
composer.lock
generated
|
@ -4,12 +4,39 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "d4b9e76dbda3af97316a38bfe163ac00",
|
"hash": "2afe3e4c1f053ce8a1dc13887ea3aa8c",
|
||||||
"content-hash": "6eb27104cc39af34f798d35fb3f381ac",
|
"content-hash": "2c86697f5f04b91631cd33dbedce3179",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "container-interop/container-interop",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/container-interop/container-interop.git",
|
||||||
|
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
||||||
|
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Interop\\Container\\": "src/Interop/Container/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
||||||
|
"time": "2014-12-30 15:22:37"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ffmpeg/ffmpeg",
|
"name": "ffmpeg/ffmpeg",
|
||||||
"version": "2.8.4",
|
"version": "dev-release",
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "xz",
|
"type": "xz",
|
||||||
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
"url": "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz",
|
||||||
|
@ -85,16 +112,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "league/uri",
|
"name": "league/uri",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/thephpleague/uri.git",
|
"url": "https://github.com/thephpleague/uri.git",
|
||||||
"reference": "a4f0ea3323745214c955af2f6451d7743f30a076"
|
"reference": "0cbce9fe7d9808690ebda67b110ad96bcae9daee"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/thephpleague/uri/zipball/a4f0ea3323745214c955af2f6451d7743f30a076",
|
"url": "https://api.github.com/repos/thephpleague/uri/zipball/0cbce9fe7d9808690ebda67b110ad96bcae9daee",
|
||||||
"reference": "a4f0ea3323745214c955af2f6451d7743f30a076",
|
"reference": "0cbce9fe7d9808690ebda67b110ad96bcae9daee",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -145,7 +172,146 @@
|
||||||
"url",
|
"url",
|
||||||
"ws"
|
"ws"
|
||||||
],
|
],
|
||||||
"time": "2016-02-18 14:46:01"
|
"time": "2016-03-24 08:38:29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mathmarques/smarty-view",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mathmarques/Smarty-View.git",
|
||||||
|
"reference": "66f4d28c564c0363eda18d3f5b85a4241b1c4ad1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/mathmarques/Smarty-View/zipball/66f4d28c564c0363eda18d3f5b85a4241b1c4ad1",
|
||||||
|
"reference": "66f4d28c564c0363eda18d3f5b85a4241b1c4ad1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5.0",
|
||||||
|
"slim/slim": "^3.0",
|
||||||
|
"smarty/smarty": "~3.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Slim\\Views\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Matheus Marques",
|
||||||
|
"email": "matheusocmarques@gmail.com",
|
||||||
|
"homepage": "http://matheusmarques.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Slim Framework 3 view helper built on top of the Smarty templating component",
|
||||||
|
"keywords": [
|
||||||
|
"framework",
|
||||||
|
"slim",
|
||||||
|
"slim 3",
|
||||||
|
"smarty",
|
||||||
|
"template",
|
||||||
|
"view"
|
||||||
|
],
|
||||||
|
"time": "2016-03-31 00:41:59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nikic/fast-route",
|
||||||
|
"version": "v1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/nikic/FastRoute.git",
|
||||||
|
"reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/8ea928195fa9b907f0d6e48312d323c1a13cc2af",
|
||||||
|
"reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"FastRoute\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nikita Popov",
|
||||||
|
"email": "nikic@php.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Fast request router for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"router",
|
||||||
|
"routing"
|
||||||
|
],
|
||||||
|
"time": "2016-06-12 19:08:51"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pimple/pimple",
|
||||||
|
"version": "v3.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/silexphp/Pimple.git",
|
||||||
|
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||||
|
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Pimple": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Pimple, a simple Dependency Injection Container",
|
||||||
|
"homepage": "http://pimple.sensiolabs.org",
|
||||||
|
"keywords": [
|
||||||
|
"container",
|
||||||
|
"dependency injection"
|
||||||
|
],
|
||||||
|
"time": "2015-09-11 15:10:35"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-message",
|
"name": "psr/http-message",
|
||||||
|
@ -196,37 +362,106 @@
|
||||||
],
|
],
|
||||||
"time": "2015-05-04 20:22:00"
|
"time": "2015-05-04 20:22:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ptachoire/process-builder-chain",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/krichprollsch/process-builder-chain.git",
|
||||||
|
"reference": "465055dbcc3b5ef792a768df935571551de4781a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/krichprollsch/process-builder-chain/zipball/465055dbcc3b5ef792a768df935571551de4781a",
|
||||||
|
"reference": "465055dbcc3b5ef792a768df935571551de4781a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"symfony/process": "~2.5 || ~3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Chain": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Pierre Tachoire",
|
||||||
|
"email": "pierre.tachoire@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Add ability to chain symfony processes",
|
||||||
|
"time": "2016-04-10 08:33:20"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "rg3/youtube-dl",
|
"name": "rg3/youtube-dl",
|
||||||
"version": "2016.03.14",
|
"version": "2016.07.26",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/rg3/youtube-dl.git",
|
"url": "https://github.com/rg3/youtube-dl.git",
|
||||||
"reference": "2016.03.14"
|
"reference": "2016.07.26"
|
||||||
},
|
},
|
||||||
"type": "library"
|
"type": "library"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rudloff/smarty-plugin-noscheme",
|
"name": "rudloff/rtmpdump-bin",
|
||||||
"version": "0.1.0",
|
"version": "2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Rudloff/smarty-plugin-noscheme.git",
|
"url": "https://github.com/Rudloff/rtmpdump-bin.git",
|
||||||
"reference": "537bcb2f7576252af70d8f9f817bfe050d873072"
|
"reference": "133cdd80e3bab66593e88a5276158596383afd97"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Rudloff/smarty-plugin-noscheme/zipball/537bcb2f7576252af70d8f9f817bfe050d873072",
|
"url": "https://api.github.com/repos/Rudloff/rtmpdump-bin/zipball/133cdd80e3bab66593e88a5276158596383afd97",
|
||||||
"reference": "537bcb2f7576252af70d8f9f817bfe050d873072",
|
"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-12 19:17:32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rudloff/smarty-plugin-noscheme",
|
||||||
|
"version": "0.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Rudloff/smarty-plugin-noscheme.git",
|
||||||
|
"reference": "7b64350bd255690e44db497e50bb5edc5e87d5e6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Rudloff/smarty-plugin-noscheme/zipball/7b64350bd255690e44db497e50bb5edc5e87d5e6",
|
||||||
|
"reference": "7b64350bd255690e44db497e50bb5edc5e87d5e6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"league/uri": "~4.0"
|
"league/uri": "~4.1.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "~2.7.6"
|
"symfony/var-dumper": "~3.0.1"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"modifier.noscheme.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
"license": [
|
"license": [
|
||||||
"GPL-3.0"
|
"GPL-3.0"
|
||||||
|
@ -240,80 +475,40 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Smarty modifier that removes the scheme in URLs",
|
"description": "Smarty modifier that removes the scheme in URLs",
|
||||||
"time": "2015-10-31 10:25:47"
|
"time": "2016-04-09 00:40:13"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "slim/slim",
|
"name": "slim/slim",
|
||||||
"version": "2.6.2",
|
"version": "3.5.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/slimphp/Slim.git",
|
"url": "https://github.com/slimphp/Slim.git",
|
||||||
"reference": "20a02782f76830b67ae56a5c08eb1f563c351a37"
|
"reference": "184352bc1913d7ba552ab4131d62f4730ddb0893"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/20a02782f76830b67ae56a5c08eb1f563c351a37",
|
"url": "https://api.github.com/repos/slimphp/Slim/zipball/184352bc1913d7ba552ab4131d62f4730ddb0893",
|
||||||
"reference": "20a02782f76830b67ae56a5c08eb1f563c351a37",
|
"reference": "184352bc1913d7ba552ab4131d62f4730ddb0893",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"container-interop/container-interop": "^1.1",
|
||||||
|
"nikic/fast-route": "^1.0",
|
||||||
|
"php": ">=5.5.0",
|
||||||
|
"pimple/pimple": "^3.0",
|
||||||
|
"psr/http-message": "^1.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"provide": {
|
||||||
"ext-mcrypt": "Required for HTTP cookie encryption"
|
"psr/http-message-implementation": "1.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"require-dev": {
|
||||||
"autoload": {
|
"phpunit/phpunit": "^4.0",
|
||||||
"psr-0": {
|
"squizlabs/php_codesniffer": "^2.5"
|
||||||
"Slim": "."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Josh Lockhart",
|
|
||||||
"email": "info@joshlockhart.com",
|
|
||||||
"homepage": "http://www.joshlockhart.com/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Slim Framework, a PHP micro framework",
|
|
||||||
"homepage": "http://github.com/codeguy/Slim",
|
|
||||||
"keywords": [
|
|
||||||
"microframework",
|
|
||||||
"rest",
|
|
||||||
"router"
|
|
||||||
],
|
|
||||||
"time": "2015-03-08 18:41:17"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "slim/views",
|
|
||||||
"version": "0.1.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/slimphp/Slim-Views.git",
|
|
||||||
"reference": "8561c785e55a39df6cb6f95c3aba3281a60ed5b0"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/slimphp/Slim-Views/zipball/8561c785e55a39df6cb6f95c3aba3281a60ed5b0",
|
|
||||||
"reference": "8561c785e55a39df6cb6f95c3aba3281a60ed5b0",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.0",
|
|
||||||
"slim/slim": ">=2.4.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"smarty/smarty": "Smarty templating system",
|
|
||||||
"twig/twig": "Twig templating system"
|
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Slim\\Views\\": "./"
|
"Slim\\": "Slim"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
@ -321,25 +516,36 @@
|
||||||
"MIT"
|
"MIT"
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Rob Allen",
|
||||||
|
"email": "rob@akrabat.com",
|
||||||
|
"homepage": "http://akrabat.com"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Josh Lockhart",
|
"name": "Josh Lockhart",
|
||||||
"email": "info@joshlockhart.com",
|
"email": "hello@joshlockhart.com",
|
||||||
"homepage": "http://www.joshlockhart.com/"
|
"homepage": "https://joshlockhart.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gabriel Manricks",
|
||||||
|
"email": "gmanricks@me.com",
|
||||||
|
"homepage": "http://gabrielmanricks.com"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Andrew Smith",
|
"name": "Andrew Smith",
|
||||||
"email": "a.smith@silentworks.co.uk",
|
"email": "a.smith@silentworks.co.uk",
|
||||||
"homepage": "http://thoughts.silentworks.co.uk/"
|
"homepage": "http://silentworks.co.uk"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Smarty and Twig View Parser package for the Slim Framework",
|
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
|
||||||
"homepage": "http://github.com/codeguy/Slim-Views",
|
"homepage": "http://slimframework.com",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"extensions",
|
"api",
|
||||||
"slimphp",
|
"framework",
|
||||||
"templating"
|
"micro",
|
||||||
|
"router"
|
||||||
],
|
],
|
||||||
"time": "2014-12-09 23:48:51"
|
"time": "2016-07-26 15:12:13"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "smarty/smarty",
|
"name": "smarty/smarty",
|
||||||
|
@ -397,17 +603,17 @@
|
||||||
"time": "2015-12-21 01:57:06"
|
"time": "2015-12-21 01:57:06"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/process",
|
||||||
"version": "v3.0.3",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c"
|
"reference": "5c11a1a4d4016662eeaf0f8757958c7de069f9a0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/b5ba64cd67ecd6887f63868fa781ca094bd1377c",
|
"url": "https://api.github.com/repos/symfony/process/zipball/5c11a1a4d4016662eeaf0f8757958c7de069f9a0",
|
||||||
"reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c",
|
"reference": "5c11a1a4d4016662eeaf0f8757958c7de069f9a0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -416,7 +622,56 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "3.0-dev"
|
"dev-master": "3.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Process\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Process Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"time": "2016-06-29 05:42:25"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/yaml",
|
||||||
|
"version": "v3.1.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
|
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
|
||||||
|
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5.9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.1-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -443,22 +698,22 @@
|
||||||
],
|
],
|
||||||
"description": "Symfony Yaml Component",
|
"description": "Symfony Yaml Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-02-23 15:16:06"
|
"time": "2016-06-29 05:41:56"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.1.1",
|
"version": "v1.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "1289d16209491b584839022f29257ad859b8532d"
|
"reference": "dff51f72b0706335131b00a7f49606168c582594"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
|
||||||
"reference": "1289d16209491b584839022f29257ad859b8532d",
|
"reference": "dff51f72b0706335131b00a7f49606168c582594",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -470,7 +725,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.1-dev"
|
"dev-master": "1.2-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -504,20 +759,20 @@
|
||||||
"portable",
|
"portable",
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"time": "2016-01-20 09:13:37"
|
"time": "2016-05-18 14:26:46"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/var-dumper",
|
"name": "symfony/var-dumper",
|
||||||
"version": "v3.0.3",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/var-dumper.git",
|
"url": "https://github.com/symfony/var-dumper.git",
|
||||||
"reference": "9a6a883c48acb215d4825ce9de61dccf93d62074"
|
"reference": "39492b8b8fe514163e677bf154fd80f6cc995759"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/9a6a883c48acb215d4825ce9de61dccf93d62074",
|
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/39492b8b8fe514163e677bf154fd80f6cc995759",
|
||||||
"reference": "9a6a883c48acb215d4825ce9de61dccf93d62074",
|
"reference": "39492b8b8fe514163e677bf154fd80f6cc995759",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -533,7 +788,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "3.0-dev"
|
"dev-master": "3.1-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -567,12 +822,14 @@
|
||||||
"debug",
|
"debug",
|
||||||
"dump"
|
"dump"
|
||||||
],
|
],
|
||||||
"time": "2016-02-13 09:23:44"
|
"time": "2016-06-29 05:41:56"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": [],
|
"stability-flags": {
|
||||||
|
"ffmpeg/ffmpeg": 20
|
||||||
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": [],
|
||||||
|
|
BIN
composer.phar
|
@ -1,6 +1,12 @@
|
||||||
youtubedl: vendor/rg3/youtube-dl/youtube_dl/__main__.py
|
youtubedl: vendor/rg3/youtube-dl/youtube_dl/__main__.py
|
||||||
python: /usr/bin/python
|
python: /usr/bin/python
|
||||||
params: --no-playlist --no-warnings -f best
|
params:
|
||||||
|
- --no-playlist
|
||||||
|
- --no-warnings
|
||||||
|
- -f best[protocol^=http]
|
||||||
|
- --playlist-end
|
||||||
|
- 1
|
||||||
curl_params:
|
curl_params:
|
||||||
convert: false
|
convert: false
|
||||||
avconv: vendor/bin/ffmpeg
|
avconv: vendor/bin/ffmpeg
|
||||||
|
rtmpdump: vendor/bin/rtmpdump
|
||||||
|
|
|
@ -11,8 +11,15 @@
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
namespace Alltube\Controller;
|
namespace Alltube\Controller;
|
||||||
|
|
||||||
use Alltube\VideoDownload;
|
use Alltube\VideoDownload;
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
|
use Symfony\Component\Process\ProcessBuilder;
|
||||||
|
use Chain\Chain;
|
||||||
|
use Slim\Http\Stream;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
use Slim\Http\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main controller
|
* Main controller
|
||||||
*
|
*
|
||||||
|
@ -26,177 +33,251 @@ use Alltube\Config;
|
||||||
* */
|
* */
|
||||||
class FrontController
|
class FrontController
|
||||||
{
|
{
|
||||||
|
public function __construct($container)
|
||||||
|
{
|
||||||
|
$this->config = Config::getInstance();
|
||||||
|
$this->download = new VideoDownload();
|
||||||
|
$this->container = $container;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display index page
|
* Display index page
|
||||||
*
|
*
|
||||||
|
* @param Request $request PSR-7 request
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static function index()
|
public function index(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
global $app;
|
$this->container->view->render(
|
||||||
$config = Config::getInstance();
|
$response,
|
||||||
$app->render(
|
|
||||||
'head.tpl',
|
'head.tpl',
|
||||||
array(
|
array(
|
||||||
'class'=>'index'
|
'class'=>'index',
|
||||||
|
'description'=>'Easily download videos from Youtube, Dailymotion, Vimeo and other websites.'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render(
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'header.tpl'
|
'header.tpl'
|
||||||
);
|
);
|
||||||
$app->render(
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'index.tpl',
|
'index.tpl',
|
||||||
array(
|
array(
|
||||||
'convert'=>$config->convert
|
'convert'=>$this->config->convert
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render('footer.tpl');
|
$this->container->view->render($response, 'footer.tpl');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a list of extractors
|
* Display a list of extractors
|
||||||
*
|
*
|
||||||
|
* @param Request $request PSR-7 request
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static function extractors()
|
public function extractors(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
global $app;
|
$this->container->view->render(
|
||||||
$app->render(
|
$response,
|
||||||
'head.tpl',
|
'head.tpl',
|
||||||
array(
|
array(
|
||||||
'class'=>'extractors'
|
'class'=>'extractors',
|
||||||
|
'title'=>'Supported websites',
|
||||||
|
'description'
|
||||||
|
=>'List of all supported websites from which Alltube Download can extract video or audio files'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render('header.tpl');
|
$this->container->view->render($response, 'header.tpl');
|
||||||
$app->render('logo.tpl');
|
$this->container->view->render($response, 'logo.tpl');
|
||||||
$app->render(
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'extractors.tpl',
|
'extractors.tpl',
|
||||||
array(
|
array(
|
||||||
'extractors'=>VideoDownload::listExtractors()
|
'extractors'=>$this->download->listExtractors()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render('footer.tpl');
|
$this->container->view->render($response, 'footer.tpl');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dislay information about the video
|
* Dislay information about the video
|
||||||
*
|
*
|
||||||
|
* @param Request $request PSR-7 request
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static function video()
|
public function video(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
global $app;
|
$params = $request->getQueryParams();
|
||||||
$config = Config::getInstance();
|
$this->config = Config::getInstance();
|
||||||
if (isset($_GET["url"])) {
|
if (isset($params["url"])) {
|
||||||
if (isset($_GET['audio'])) {
|
if (isset($params['audio'])) {
|
||||||
try {
|
try {
|
||||||
$video = VideoDownload::getJSON($_GET["url"]);
|
$url = $this->download->getURL($params["url"], 'mp3[protocol^=http]');
|
||||||
|
return $response->withRedirect($url);
|
||||||
//Vimeo needs a correct user-agent
|
|
||||||
$UA = VideoDownload::getUA();
|
|
||||||
ini_set(
|
|
||||||
'user_agent',
|
|
||||||
$UA
|
|
||||||
);
|
|
||||||
$url_info = parse_url($video->url);
|
|
||||||
if ($url_info['scheme'] == 'rtmp') {
|
|
||||||
ob_end_flush();
|
|
||||||
header(
|
|
||||||
'Content-Disposition: attachment; filename="'.
|
|
||||||
html_entity_decode(
|
|
||||||
pathinfo(
|
|
||||||
VideoDownload::getFilename(
|
|
||||||
$video->webpage_url
|
|
||||||
), PATHINFO_FILENAME
|
|
||||||
).'.mp3', ENT_COMPAT, 'ISO-8859-1'
|
|
||||||
).'"'
|
|
||||||
);
|
|
||||||
header("Content-Type: audio/mpeg");
|
|
||||||
passthru(
|
|
||||||
'/usr/bin/rtmpdump -q -r '.escapeshellarg($video->url).
|
|
||||||
' | '.$config->avconv.
|
|
||||||
' -v quiet -i - -f mp3 -vn pipe:1'
|
|
||||||
);
|
|
||||||
exit;
|
|
||||||
} else {
|
|
||||||
ob_end_flush();
|
|
||||||
header(
|
|
||||||
'Content-Disposition: attachment; filename="'.
|
|
||||||
html_entity_decode(
|
|
||||||
pathinfo(
|
|
||||||
VideoDownload::getFilename(
|
|
||||||
$video->webpage_url
|
|
||||||
), PATHINFO_FILENAME
|
|
||||||
).'.mp3', ENT_COMPAT, 'ISO-8859-1'
|
|
||||||
).'"'
|
|
||||||
);
|
|
||||||
header("Content-Type: audio/mpeg");
|
|
||||||
passthru(
|
|
||||||
'curl '.$config->curl_params.
|
|
||||||
' --user-agent '.escapeshellarg($UA).
|
|
||||||
' '.escapeshellarg($video->url).
|
|
||||||
' | '.$config->avconv.
|
|
||||||
' -v quiet -i - -f mp3 -vn pipe:1'
|
|
||||||
);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$error = $e->getMessage();
|
$video = $this->download->getJSON($params["url"], 'bestaudio/best');
|
||||||
|
|
||||||
|
if (!shell_exec('which '.$this->config->avconv)) {
|
||||||
|
throw(new \Exception('Can\'t find avconv or ffmpeg'));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
try {
|
$avconvProc = ProcessBuilder::create(
|
||||||
$video = VideoDownload::getJSON($_GET["url"]);
|
|
||||||
$app->render(
|
|
||||||
'head.tpl',
|
|
||||||
array(
|
array(
|
||||||
'class'=>'video'
|
$this->config->avconv,
|
||||||
|
'-v', 'quiet',
|
||||||
|
'-i', '-',
|
||||||
|
'-f', 'mp3',
|
||||||
|
'-vn',
|
||||||
|
'pipe:1'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render(
|
|
||||||
|
//Vimeo needs a correct user-agent
|
||||||
|
ini_set(
|
||||||
|
'user_agent',
|
||||||
|
$video->http_headers->{'User-Agent'}
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $response->withHeader(
|
||||||
|
'Content-Disposition',
|
||||||
|
'attachment; filename="'.
|
||||||
|
html_entity_decode(
|
||||||
|
pathinfo(
|
||||||
|
$video->_filename,
|
||||||
|
PATHINFO_FILENAME
|
||||||
|
).'.mp3',
|
||||||
|
ENT_COMPAT,
|
||||||
|
'ISO-8859-1'
|
||||||
|
).'"'
|
||||||
|
);
|
||||||
|
$response = $response->withHeader('Content-Type', 'audio/mpeg');
|
||||||
|
|
||||||
|
if (parse_url($video->url, PHP_URL_SCHEME) == 'rtmp') {
|
||||||
|
if (!shell_exec('which '.$this->config->rtmpdump)) {
|
||||||
|
throw(new \Exception('Can\'t find rtmpdump'));
|
||||||
|
}
|
||||||
|
$builder = new ProcessBuilder(
|
||||||
|
array(
|
||||||
|
$this->config->rtmpdump,
|
||||||
|
'-q',
|
||||||
|
'-r',
|
||||||
|
$video->url,
|
||||||
|
'--pageUrl', $video->webpage_url
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (isset($video->player_url)) {
|
||||||
|
$builder->add('--swfVfy');
|
||||||
|
$builder->add($video->player_url);
|
||||||
|
}
|
||||||
|
if (isset($video->flash_version)) {
|
||||||
|
$builder->add('--flashVer');
|
||||||
|
$builder->add($video->flash_version);
|
||||||
|
}
|
||||||
|
if (isset($video->play_path)) {
|
||||||
|
$builder->add('--playpath');
|
||||||
|
$builder->add($video->play_path);
|
||||||
|
}
|
||||||
|
foreach ($video->rtmp_conn as $conn) {
|
||||||
|
$builder->add('--conn');
|
||||||
|
$builder->add($conn);
|
||||||
|
}
|
||||||
|
$chain = new Chain($builder->getProcess());
|
||||||
|
$chain->add('|', $avconvProc);
|
||||||
|
} else {
|
||||||
|
if (!shell_exec('which curl')) {
|
||||||
|
throw(new \Exception('Can\'t find curl'));
|
||||||
|
}
|
||||||
|
$chain = new Chain(
|
||||||
|
ProcessBuilder::create(
|
||||||
|
array_merge(
|
||||||
|
array(
|
||||||
|
'curl',
|
||||||
|
'--silent',
|
||||||
|
'--user-agent', $video->http_headers->{'User-Agent'},
|
||||||
|
$video->url
|
||||||
|
),
|
||||||
|
$this->config->curl_params
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$chain->add('|', $avconvProc);
|
||||||
|
}
|
||||||
|
if ($request->isGet()) {
|
||||||
|
$response = $response->withBody(new Stream(popen($chain->getProcess()->getCommandLine(), 'r')));
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$video = $this->download->getJSON($params["url"]);
|
||||||
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
|
'head.tpl',
|
||||||
|
array(
|
||||||
|
'class'=>'video',
|
||||||
|
'title'=>$video->title,
|
||||||
|
'description'=>'Download "'.$video->title.'" from '.$video->extractor_key
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'video.tpl',
|
'video.tpl',
|
||||||
array(
|
array(
|
||||||
'video'=>$video
|
'video'=>$video
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render('footer.tpl');
|
$this->container->view->render($response, 'footer.tpl');
|
||||||
} catch (\Exception $e) {
|
}
|
||||||
$error = $e->getMessage();
|
} else {
|
||||||
|
return $response->withRedirect($this->container->get('router')->pathFor('index'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (isset($error)) {
|
public function error(Request $request, Response $response, \Exception $exception)
|
||||||
$app->render(
|
{
|
||||||
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'head.tpl',
|
'head.tpl',
|
||||||
array(
|
array(
|
||||||
'class'=>'video'
|
'class'=>'video',
|
||||||
|
'title'=>'Error'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render(
|
$this->container->view->render(
|
||||||
|
$response,
|
||||||
'error.tpl',
|
'error.tpl',
|
||||||
array(
|
array(
|
||||||
'errors'=>$error
|
'errors'=>$exception->getMessage()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$app->render('footer.tpl');
|
$this->container->view->render($response, 'footer.tpl');
|
||||||
}
|
return $response->withStatus(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect to video file
|
* Redirect to video file
|
||||||
*
|
*
|
||||||
|
* @param Request $request PSR-7 request
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static function redirect()
|
public function redirect(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
global $app;
|
$params = $request->getQueryParams();
|
||||||
if (isset($_GET["url"])) {
|
if (isset($params["url"])) {
|
||||||
try {
|
try {
|
||||||
$video = VideoDownload::getURL($_GET["url"]);
|
$url = $this->download->getURL($params["url"], $params["format"]);
|
||||||
$app->redirect($video['url']);
|
return $response->withRedirect($url);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$app->response->headers->set('Content-Type', 'text/plain');
|
$response->getBody()->write($e->getMessage());
|
||||||
echo $e->getMessage().PHP_EOL;
|
return $response->withHeader('Content-Type', 'text/plain');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,18 +285,22 @@ class FrontController
|
||||||
/**
|
/**
|
||||||
* Output JSON info about the video
|
* Output JSON info about the video
|
||||||
*
|
*
|
||||||
|
* @param Request $request PSR-7 request
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static function json()
|
public function json(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
global $app;
|
$params = $request->getQueryParams();
|
||||||
if (isset($_GET["url"])) {
|
if (isset($params["url"])) {
|
||||||
$app->response->headers->set('Content-Type', 'application/json');
|
|
||||||
try {
|
try {
|
||||||
$video = VideoDownload::getJSON($_GET["url"]);
|
$video = $this->download->getJSON($params["url"]);
|
||||||
echo json_encode($video);
|
return $response->withJson($video);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
echo json_encode(array('success'=>false, 'error'=>$e->getMessage()));
|
return $response->withJson(
|
||||||
|
array('success'=>false, 'error'=>$e->getMessage())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,7 +565,12 @@ h1 {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monospace {
|
||||||
|
font-family:monospace;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
|
.formats,
|
||||||
.thumb {
|
.thumb {
|
||||||
width:90%;
|
width:90%;
|
||||||
}
|
}
|
||||||
|
@ -653,3 +658,9 @@ h1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media all and (display-mode: standalone) {
|
||||||
|
.bookmarklet_wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!Doctype HTML>
|
<!Doctype HTML>
|
||||||
<html lang="en" itemscope itemtype="http://schema.org/WebApplication">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<h1><img itemprop="image" class="logo" src="img/logo.png"
|
<h1><img class="logo" src="img/logo.png"
|
||||||
alt="AllTube Download" width="328" height="284"></h1>
|
alt="AllTube Download" width="328" height="284"></h1>
|
||||||
<div>An error occurred in the application and your page could not be served. Please try again in a few moments.</div>
|
<div>An error occurred in the application and your page could not be served. Please try again in a few moments.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
BIN
img/favicon.png
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
img/logo.png
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
img/logo_250.png
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
BIN
img/logo_60.png
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
BIN
img/logo_90.png
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
img/logo_app.png
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
BIN
img/mp3hover.png
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 728 B |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 127 KiB |
BIN
img/twitter.png
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.5 KiB |
50
index.php
|
@ -14,35 +14,47 @@
|
||||||
* */
|
* */
|
||||||
require_once __DIR__.'/vendor/autoload.php';
|
require_once __DIR__.'/vendor/autoload.php';
|
||||||
use Alltube\VideoDownload;
|
use Alltube\VideoDownload;
|
||||||
|
use Alltube\Controller\FrontController;
|
||||||
|
|
||||||
|
if (strpos($_SERVER['REQUEST_URI'], '/index.php') !== false) {
|
||||||
|
header('Location: '.str_ireplace('/index.php', '/', $_SERVER['REQUEST_URI']));
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app = new \Slim\App();
|
||||||
|
$container = $app->getContainer();
|
||||||
|
$container['view'] = function ($c) {
|
||||||
|
$view = new \Slim\Views\Smarty(__DIR__.'/templates/');
|
||||||
|
|
||||||
|
$view->addSlimPlugins($c['router'], $c['request']->getUri());
|
||||||
|
$view->registerPlugin('modifier', 'noscheme', 'Smarty_Modifier_noscheme');
|
||||||
|
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
};
|
||||||
|
|
||||||
|
$controller = new FrontController($container);
|
||||||
|
|
||||||
|
$container['errorHandler'] = array($controller, 'error');
|
||||||
|
|
||||||
$app = new \Slim\Slim(
|
|
||||||
array(
|
|
||||||
'view' => new \Slim\Views\Smarty()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$view = $app->view();
|
|
||||||
$view->parserExtensions = array(
|
|
||||||
__DIR__.'/vendor/slim/views/SmartyPlugins',
|
|
||||||
__DIR__.'/vendor/rudloff/smarty-plugin-noscheme/'
|
|
||||||
);
|
|
||||||
$app->get(
|
$app->get(
|
||||||
'/',
|
'/',
|
||||||
array('Alltube\Controller\FrontController', 'index')
|
array($controller, 'index')
|
||||||
);
|
)->setName('index');
|
||||||
$app->get(
|
$app->get(
|
||||||
'/extractors',
|
'/extractors',
|
||||||
array('Alltube\Controller\FrontController', 'extractors')
|
array($controller, 'extractors')
|
||||||
)->name('extractors');
|
)->setName('extractors');
|
||||||
$app->get(
|
$app->get(
|
||||||
'/video',
|
'/video',
|
||||||
array('Alltube\Controller\FrontController', 'video')
|
array($controller, 'video')
|
||||||
)->name('video');
|
)->setName('video');
|
||||||
$app->get(
|
$app->get(
|
||||||
'/redirect',
|
'/redirect',
|
||||||
array('Alltube\Controller\FrontController', 'redirect')
|
array($controller, 'redirect')
|
||||||
);
|
)->setName('redirect');
|
||||||
$app->get(
|
$app->get(
|
||||||
'/json',
|
'/json',
|
||||||
array('Alltube\Controller\FrontController', 'json')
|
array($controller, 'json')
|
||||||
);
|
);
|
||||||
$app->run();
|
$app->run();
|
||||||
|
|
117
js/cast.js
|
@ -1,68 +1,69 @@
|
||||||
/*global chrome*/
|
/*global chrome*/
|
||||||
/*jslint devel: true, browser: true */
|
/*jslint browser: true, nomen: true */
|
||||||
var launchBtn, disabledBtn, stopBtn;
|
var castModule = (function () {
|
||||||
var session, currentMedia;
|
|
||||||
|
|
||||||
function receiverListener(e) {
|
|
||||||
'use strict';
|
'use strict';
|
||||||
console.log('receiverListener', e);
|
var launchBtn, disabledBtn, stopBtn, session;
|
||||||
}
|
|
||||||
|
|
||||||
function onMediaDiscovered(how, media) {
|
function receiverListener(e) {
|
||||||
'use strict';
|
return (e === chrome.cast.ReceiverAvailability.AVAILABLE);
|
||||||
console.log('onMediaDiscovered', how);
|
}
|
||||||
currentMedia = media;
|
|
||||||
|
function onMediaDiscovered() {
|
||||||
if (launchBtn) {
|
if (launchBtn) {
|
||||||
stopBtn.classList.remove('cast_hidden');
|
stopBtn.classList.remove('cast_hidden');
|
||||||
launchBtn.classList.add('cast_hidden');
|
launchBtn.classList.add('cast_hidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sessionListener(e) {
|
function onStopCast() {
|
||||||
'use strict';
|
stopBtn.classList.add('cast_hidden');
|
||||||
|
launchBtn.classList.remove('cast_hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStopCastError(e) {
|
||||||
|
onStopCast();
|
||||||
|
throw e.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateListener() {
|
||||||
|
if (session.status !== chrome.cast.SessionStatus.CONNECTED) {
|
||||||
|
onStopCast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sessionListener(e) {
|
||||||
session = e;
|
session = e;
|
||||||
session.addMediaListener(onMediaDiscovered.bind(this, 'addMediaListener'));
|
session.addMediaListener(onMediaDiscovered.bind(this, 'addMediaListener'));
|
||||||
|
session.addUpdateListener(updateListener.bind(this));
|
||||||
if (session.media.length !== 0) {
|
if (session.media.length !== 0) {
|
||||||
onMediaDiscovered('onRequestSessionSuccess', session.media[0]);
|
onMediaDiscovered('onRequestSessionSuccess', session.media[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStopCast() {
|
function stopCast() {
|
||||||
'use strict';
|
session.stop(onStopCast, onStopCastError);
|
||||||
stopBtn.classList.add('cast_hidden');
|
}
|
||||||
launchBtn.classList.remove('cast_hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopCast() {
|
function onMediaError(e) {
|
||||||
'use strict';
|
|
||||||
session.stop(onStopCast);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMediaError() {
|
|
||||||
'use strict';
|
|
||||||
console.log('onMediaError');
|
|
||||||
stopCast();
|
stopCast();
|
||||||
}
|
throw e.description;
|
||||||
|
}
|
||||||
|
|
||||||
function onRequestSessionSuccess(e) {
|
function onRequestSessionSuccess(e) {
|
||||||
'use strict';
|
|
||||||
session = e;
|
session = e;
|
||||||
var videoLink = document.getElementById('video_link'), videoURL = videoLink.dataset.video, mediaInfo = new chrome.cast.media.MediaInfo(videoURL, 'video/' + videoLink.dataset.ext), request = new chrome.cast.media.LoadRequest(mediaInfo);
|
var videoLink = document.getElementById('video_link'), videoURL = videoLink.dataset.video, mediaInfo = new chrome.cast.media.MediaInfo(videoURL, 'video/' + videoLink.dataset.ext), request = new chrome.cast.media.LoadRequest(mediaInfo);
|
||||||
session.loadMedia(request, onMediaDiscovered.bind(this, 'loadMedia'), onMediaError);
|
session.loadMedia(request, onMediaDiscovered.bind(this, 'loadMedia'), onMediaError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLaunchError(e) {
|
function onLaunchError(e) {
|
||||||
'use strict';
|
throw e.description;
|
||||||
console.log('onLaunchError', e.description);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function launchCast() {
|
function launchCast() {
|
||||||
'use strict';
|
|
||||||
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError);
|
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInitSuccess() {
|
function onInitSuccess() {
|
||||||
'use strict';
|
|
||||||
launchBtn = document.getElementById('cast_btn_launch');
|
launchBtn = document.getElementById('cast_btn_launch');
|
||||||
disabledBtn = document.getElementById('cast_disabled');
|
disabledBtn = document.getElementById('cast_disabled');
|
||||||
stopBtn = document.getElementById('cast_btn_stop');
|
stopBtn = document.getElementById('cast_btn_stop');
|
||||||
|
@ -72,26 +73,34 @@ function onInitSuccess() {
|
||||||
launchBtn.addEventListener('click', launchCast, false);
|
launchBtn.addEventListener('click', launchCast, false);
|
||||||
stopBtn.addEventListener('click', stopCast, false);
|
stopBtn.addEventListener('click', stopCast, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onError() {
|
function onError(e) {
|
||||||
'use strict';
|
throw e.code;
|
||||||
console.log('onError');
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function initializeCastApi() {
|
function initializeCastApi() {
|
||||||
'use strict';
|
|
||||||
var sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID), apiConfig = new chrome.cast.ApiConfig(sessionRequest, sessionListener, receiverListener, chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED);
|
var sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID), apiConfig = new chrome.cast.ApiConfig(sessionRequest, sessionListener, receiverListener, chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED);
|
||||||
chrome.cast.initialize(apiConfig, onInitSuccess, onError);
|
chrome.cast.initialize(apiConfig, onInitSuccess, onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadCastApi(loaded, errorInfo) {
|
function loadCastApi(loaded, errorInfo) {
|
||||||
'use strict';
|
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
initializeCastApi();
|
initializeCastApi();
|
||||||
} else {
|
} else {
|
||||||
console.log(errorInfo);
|
throw errorInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
window['__onGCastApiAvailable'] = loadCastApi;
|
return {
|
||||||
|
init: function () {
|
||||||
|
var intro = document.getElementById('download_intro');
|
||||||
|
if (intro) {
|
||||||
|
intro.insertAdjacentHTML('beforeend', '<img class="cast_icon" id="cast_disabled" src="img/ic_media_route_disabled_holo_light.png" alt="" title="Google Cast is not supported on this browser." /> <img class="cast_btn cast_hidden cast_icon" id="cast_btn_launch" src="img/ic_media_route_off_holo_light.png" title="Cast to ChromeCast" alt="Google Cast™" /> <img src="img/ic_media_route_on_holo_light.png" alt="Casting to ChromeCast…" title="Stop casting" id="cast_btn_stop" class="cast_btn cast_hidden cast_icon" />');
|
||||||
|
window.__onGCastApiAvailable = loadCastApi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
window.addEventListener('load', castModule.init, false);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!Doctype HTML>
|
<!Doctype HTML>
|
||||||
<html lang="en" itemscope itemtype="http://schema.org/WebApplication">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<h1><img itemprop="image" class="logo" src="img/logo.png"
|
<h1><img class="logo" src="img/logo.png"
|
||||||
alt="AllTube Download" width="328" height="284"></h1>
|
alt="AllTube Download" width="328" height="284"></h1>
|
||||||
<div>This application is undergoing maintenance right now. Please check back later.</div>
|
<div>This application is undergoing maintenance right now. Please check back later.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"short_name": "AllTube",
|
"short_name": "AllTube",
|
||||||
"name": "AllTube Download",
|
"name": "AllTube Download",
|
||||||
"display": "minimal-ui",
|
"description": "Easily download videos from Youtube, Dailymotion, Vimeo and other websites",
|
||||||
|
"display": "standalone",
|
||||||
"icons": [{
|
"icons": [{
|
||||||
"src": "img/favicon.png",
|
"src": "img/favicon.png",
|
||||||
"sizes": "32x32",
|
"sizes": "32x32",
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}],
|
}],
|
||||||
"lang": "en",
|
"lang": "en",
|
||||||
"start_url": "./index.php",
|
"start_url": "./",
|
||||||
"theme_color": "#4F4F4F"
|
"theme_color": "#4F4F4F",
|
||||||
|
"orientation": "portrait"
|
||||||
}
|
}
|
||||||
|
|
16
package.json
|
@ -1,23 +1,25 @@
|
||||||
{
|
{
|
||||||
"name": "alltube",
|
"name": "alltube",
|
||||||
"version": "0.4.5",
|
"version": "0.5.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"grunt": "~0.4.5",
|
"grunt": "~1.0.1",
|
||||||
"grunt-cli": "~0.1.13",
|
"grunt-cli": "~1.2.0",
|
||||||
"grunt-contrib-cssmin": "~1.0.0",
|
"grunt-contrib-cssmin": "~1.0.0",
|
||||||
"grunt-contrib-uglify": "~1.0.0",
|
"grunt-contrib-uglify": "~1.0.0",
|
||||||
"grunt-contrib-watch": "~0.6.1",
|
"grunt-contrib-watch": "~1.0.0",
|
||||||
"grunt-phpcs": "~0.4.0",
|
"grunt-phpcs": "~0.4.0",
|
||||||
"grunt-phpunit": "~0.3.6",
|
"grunt-phpunit": "~0.3.6",
|
||||||
"grunt-contrib-compress": "~1.1.1",
|
"grunt-contrib-compress": "~1.3.0",
|
||||||
"bower": "~1.7.1"
|
"bower": "~1.7.1",
|
||||||
|
"grunt-githash": "~0.1.3",
|
||||||
|
"grunt-jslint": "~1.1.14"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Rudloff/alltube.git"
|
"url": "https://github.com/Rudloff/alltube.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "./node_modules/bower/bin/bower install; ./node_modules/grunt-cli/bin/grunt"
|
"postinstall": "node node_modules/bower/bin/bower install && node node_modules/grunt-cli/bin/grunt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,3 @@
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</i></p>
|
</i></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer_wrapper">
|
<div class="footer_wrapper">
|
||||||
Code by <a rel="author" target="blank" itemprop="author"
|
Code by <a rel="author" target="blank"
|
||||||
href="http://rudloff.pro/">Pierre Rudloff</a>
|
href="http://rudloff.pro/">Pierre Rudloff</a>
|
||||||
· Design by
|
· Design by
|
||||||
<a rel="author" itemprop="author" target="blank"
|
<a rel="author" target="blank"
|
||||||
href="http://olivierhaquette.fr">Olivier Haquette</a>
|
href="http://olivierhaquette.fr">Olivier Haquette</a>
|
||||||
·
|
·
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
|
@ -17,5 +17,6 @@
|
||||||
·
|
·
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="{base_url|noscheme}/dist/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,31 +1,24 @@
|
||||||
<!Doctype HTML>
|
<!Doctype HTML>
|
||||||
<html lang="en" itemscope itemtype="http://schema.org/WebApplication">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name=viewport content="width=device-width, initial-scale=1">
|
<meta name=viewport content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="Easily download videos from Youtube, Dailymotion, Vimeo and other websites." />
|
{if isset($description)}
|
||||||
<link rel="stylesheet" href="{siteUrl|noscheme|replace:'index.php':'' url='dist/main.css'}" />
|
<meta name="description" content="{$description|escape}" />
|
||||||
<link rel="author" href="https://plus.google.com/110403274854419000481?rel=author" />
|
<meta name="twitter:description" content="{$description|escape}" />
|
||||||
<link rel="author" href="https://plus.google.com/103696815796116179392?rel=author" />
|
<meta property="og:description" content="{$description|escape}" />
|
||||||
<link href="https://plus.google.com/108799967445657477255" rel="publisher" />
|
{/if}
|
||||||
<title itemprop="name">AllTube Download</title>
|
<link rel="stylesheet" href="{base_url|noscheme}/dist/main.css" />
|
||||||
<meta itemprop="url" content="{siteUrl}" />
|
<title>AllTube Download{if isset($title)} - {$title|escape}{/if}</title>
|
||||||
<link rel="canonical" href="{currentUrl|replace:{siteUrl}:'http://www.alltubedownload.net/'}" />
|
<link rel="canonical" href="//{$smarty.server.HTTP_HOST|cat:$smarty.server.REQUEST_URI|replace:{base_url|noscheme}:'http://www.alltubedownload.net'}" />
|
||||||
<link rel="icon" href="{siteUrl|noscheme|replace:'index.php':'' url='img/favicon.png'}" />
|
<link rel="icon" href="{base_url|noscheme}/img/favicon.png" />
|
||||||
<meta property="og:url" content="{siteUrl}" />
|
<meta property="og:title" content="AllTube Download{if isset($title)} - {$title|escape}{/if}" />
|
||||||
<meta property="og:title" content="AllTube Download" />
|
<meta property="og:image" content="{base_url}/img/logo.png" />
|
||||||
<meta property="og:description" content="Easily download videos from Youtube, Dailymotion, Vimeo and other websites." />
|
|
||||||
<meta property="og:image" content="{siteUrl|replace:'index.php':'' url='img/logo.png'}" />
|
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary" />
|
||||||
<meta name="twitter:title" content="AllTube Download" />
|
<meta name="twitter:title" content="AllTube Download{if isset($title)} - {$title|escape}{/if}" />
|
||||||
<meta name="twitter:image" content="{siteUrl|replace:'index.php':'' url='img/logo.png'}" />
|
<meta name="twitter:image" content="{base_url}/img/logo.png" />
|
||||||
<meta name="twitter:creator" content="@Tael67" />
|
<meta name="twitter:creator" content="@Tael67" />
|
||||||
<meta name="twitter:description" content="Easily download videos from Youtube, Dailymotion, Vimeo and other websites." />
|
|
||||||
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>
|
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>
|
||||||
<script src="{siteUrl|noscheme|replace:'index.php':'' url='dist/main.js'}"></script>
|
|
||||||
<meta itemprop="applicationCategory" content="Download" />
|
|
||||||
<meta itemprop="operatingSystem" content="Linux" />
|
|
||||||
<meta itemprop="operatingSystem" content="Mac OS X" />
|
|
||||||
<meta name="theme-color" content="#4F4F4F">
|
<meta name="theme-color" content="#4F4F4F">
|
||||||
<link rel="manifest" href="manifest.json" />
|
<link rel="manifest" href="manifest.json" />
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<header>
|
<header>
|
||||||
<div class="social">
|
<div class="social">
|
||||||
<a class="twitter" href="http://twitter.com/home?status={siteUrl|urlencode}" target="_blank">
|
<a class="twitter" href="http://twitter.com/home?status={base_url|urlencode}" target="_blank">
|
||||||
Share on Twitter<div class="twittermask"></div></a>
|
Share on Twitter<div class="twittermask"></div></a>
|
||||||
<a class="facebook" href="https://www.facebook.com/sharer/sharer.php?u={siteUrl|urlencode}" target="_blank">Share on Facebook<div class="facebookmask"></div></a>
|
<a class="facebook" href="https://www.facebook.com/sharer/sharer.php?u={base_url|urlencode}" target="_blank">Share on Facebook<div class="facebookmask"></div></a>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div><img itemprop="image" class="logo" src="{siteUrl|noscheme|replace:'index.php':'' url='img/logo.png'}"
|
<div><img class="logo" src="{base_url|noscheme}/img/logo.png"
|
||||||
alt="AllTube Download" width="328" height="284"></div>
|
alt="AllTube Download" width="328" height="284"></div>
|
||||||
<form action="{urlFor name="video"}">
|
<form action="{path_for name="video"}">
|
||||||
<label class="labelurl" for="url">
|
<label class="labelurl" for="url">
|
||||||
Copy here the URL of your video (Youtube, Dailymotion, etc.)
|
Copy here the URL of your video (Youtube, Dailymotion, etc.)
|
||||||
</label>
|
</label>
|
||||||
|
@ -20,10 +20,10 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<a class="combatiblelink" href="{urlFor name="extractors"}">See all supported websites</a>
|
<a class="combatiblelink" href="{path_for name="extractors"}">See all supported websites</a>
|
||||||
<div id="bookmarklet">
|
<div id="bookmarklet" class="bookmarklet_wrapper">
|
||||||
<p> Drag this to your bookmarks bar: </p>
|
<p> Drag this to your bookmarks bar: </p>
|
||||||
<a class="bookmarklet" href="javascript:window.location='{siteUrl withUri=false}{urlFor name='video'}?url='+encodeURIComponent(location.href);">Bookmarklet</a>
|
<a class="bookmarklet" href="javascript:window.location='{base_url|noscheme}{path_for name='video'}?url='+encodeURIComponent(location.href);">Bookmarklet</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<h1 class="logobis">
|
<h1 class="logobis">
|
||||||
<a class="logocompatible" href="{siteUrl}">
|
<a class="logocompatible" href="{base_url|noscheme}">
|
||||||
AllTube Download<span class="logocompatiblemask"><img src="{siteUrl|noscheme|replace:'index.php':'' url='img/logocompatiblemask.png'}" width="447" height="107" alt="" /></span>
|
AllTube Download<span class="logocompatiblemask"><img src="{base_url|noscheme}/img/logocompatiblemask.png" width="447" height="107" alt="" /></span>
|
||||||
</a></h1>
|
</a></h1>
|
||||||
|
|
|
@ -2,49 +2,85 @@
|
||||||
<div itemscope itemtype="http://schema.org/VideoObject">
|
<div itemscope itemtype="http://schema.org/VideoObject">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
{include file="logo.tpl"}
|
{include file="logo.tpl"}
|
||||||
<p>You are going to download<i itemprop="name">
|
<p id="download_intro">You are going to download<i itemprop="name">
|
||||||
<a itemprop="url" id="video_link"
|
<a itemprop="url" id="video_link"
|
||||||
data-ext="{$video->ext}"
|
data-ext="{$video->ext}"
|
||||||
data-video="{$video->url|escape}"
|
data-video="{$video->url|escape}"
|
||||||
href="{$video->webpage_url}">
|
href="{$video->webpage_url}">
|
||||||
{$video->title}</a></i>.
|
{$video->title}</a></i>.
|
||||||
<img class="cast_icon" id="cast_disabled"
|
</p>
|
||||||
src="{siteUrl|noscheme|replace:'index.php':'' url='img/ic_media_route_disabled_holo_light.png'}"
|
|
||||||
alt="Google Cast™ is disabled"
|
|
||||||
title="Google Cast is not supported on this browser." />
|
|
||||||
<img class="cast_btn cast_hidden cast_icon" id="cast_btn_launch"
|
|
||||||
src="{siteUrl|noscheme|replace:'index.php':'' url='img/ic_media_route_off_holo_light.png'}"
|
|
||||||
title="Cast to ChromeCast" alt="Google Cast™" />
|
|
||||||
<img src="{siteUrl|noscheme|replace:'index.php':'' url='img/ic_media_route_on_holo_light.png'}"
|
|
||||||
alt="Casting to ChromeCast…" title="Stop casting"
|
|
||||||
id="cast_btn_stop" class="cast_btn cast_hidden cast_icon" /></p>
|
|
||||||
{if isset($video->thumbnail)}
|
{if isset($video->thumbnail)}
|
||||||
<img itemprop="image" class="thumb" src="{$video->thumbnail}" alt="" />
|
<img itemprop="thumbnailUrl" class="thumb" src="{$video->thumbnail}" alt="" />
|
||||||
|
{/if}
|
||||||
|
{if isset($video->description)}
|
||||||
|
<meta itemprop="description" content="{$video->description|escape}" />
|
||||||
|
{/if}
|
||||||
|
{if isset($video->upload_date)}
|
||||||
|
<meta itemprop="uploadDate" content="{$video->upload_date}" />
|
||||||
{/if}
|
{/if}
|
||||||
<br/>
|
<br/>
|
||||||
<input type="hidden" name="url"
|
|
||||||
value="{$video->webpage_url}" />
|
|
||||||
{if isset($video->formats)}
|
{if isset($video->formats)}
|
||||||
<h3>Available formats:</h3>
|
<h3><label for="format">Available formats:</label></h3>
|
||||||
<p>(You might have to do a <i>Right click > Save as</i>)</p>
|
<form action="{path_for name="redirect"}">
|
||||||
<ul id="format" class="format">
|
<input type="hidden" name="url" value="{$video->webpage_url}" />
|
||||||
<li class="best" itemprop="encoding" itemscope
|
<select name="format" id="format" class="formats monospace">
|
||||||
itemtype="http://schema.org/VideoObject">
|
<optgroup label="Generic formats">
|
||||||
<a download="{$video->_filename}" itemprop="contentUrl"
|
<option value="best[protocol^=http]">
|
||||||
href="{$video->url|escape}">
|
{strip}
|
||||||
<b>Best</b> (<span itemprop="encodingFormat">{$video->ext}</span>)
|
Best ({$video->ext}
|
||||||
</a></li>
|
{if isset($video->filesize)}
|
||||||
|
{$video->filesize}
|
||||||
|
{/if}
|
||||||
|
)
|
||||||
|
{/strip}
|
||||||
|
</option>
|
||||||
|
<option value="worst[protocol^=http]">
|
||||||
|
Worst
|
||||||
|
</option>
|
||||||
|
</optgroup>
|
||||||
|
<optgroup label="Detailed formats" class="monospace">
|
||||||
{foreach $video->formats as $format}
|
{foreach $video->formats as $format}
|
||||||
<li itemprop="encoding"
|
{if $format->protocol|in_array:array('http', 'https')}
|
||||||
itemscope itemtype="http://schema.org/VideoObject">
|
{strip}
|
||||||
<a download="{$video->_filename|replace:$video->ext:$format->ext}" itemprop="contentUrl"
|
<option value="{$format->format_id}">
|
||||||
href="{$format->url|escape}">
|
{$format->ext}
|
||||||
<span itemprop="videoQuality">{$format->format}</span> (<span itemprop="encodingFormat">{$format->ext}</span>)
|
{for $foo=1 to (5 - ($format->ext|strlen))}
|
||||||
</a></li>
|
|
||||||
|
{/for}
|
||||||
|
{if isset($format->width)}
|
||||||
|
{$format->width}x{$format->height}
|
||||||
|
{for $foo=1 to (10 - (("{$format->width}x{$format->height}")|strlen))}
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
{else}
|
||||||
|
{for $foo=1 to 10}
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
{/if}
|
||||||
|
{if isset($format->filesize)}
|
||||||
|
{($format->filesize/1000000)|round:2} MB
|
||||||
|
{for $foo=1 to (7 - (($format->filesize/1000000)|round:2|strlen))}
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
{else}
|
||||||
|
{for $foo=1 to 10}
|
||||||
|
|
||||||
|
{/for}
|
||||||
|
{/if}
|
||||||
|
{if isset($format->format_note)}
|
||||||
|
{$format->format_note}
|
||||||
|
{/if}
|
||||||
|
({$format->format_id})
|
||||||
|
</option>
|
||||||
|
{/strip}
|
||||||
|
{/if}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</ul><br/><br/>
|
</optgroup>
|
||||||
|
</select><br/><br/>
|
||||||
|
<input class="downloadBtn" type="submit" value="Download" /><br/>
|
||||||
|
</form>
|
||||||
{else}
|
{else}
|
||||||
<input type="hidden" name="format" value="best" />
|
<input type="hidden" name="format" value="best[protocol^=http]" />
|
||||||
<a class="downloadBtn"
|
<a class="downloadBtn"
|
||||||
href="{$video->url|escape}">Download</a><br/>
|
href="{$video->url|escape}">Download</a><br/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +25,7 @@ use Alltube\Config;
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
class ConfigTest extends PHPUnit_Framework_TestCase
|
class ConfigTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\VideoDownload;
|
use Alltube\VideoDownload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,26 +25,21 @@ use Alltube\VideoDownload;
|
||||||
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
* @license GNU General Public License http://www.gnu.org/licenses/gpl.html
|
||||||
* @link http://rudloff.pro
|
* @link http://rudloff.pro
|
||||||
* */
|
* */
|
||||||
class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
class VideoDownloadTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
/**
|
protected function setUp()
|
||||||
* Test getUA function
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function testGetUA()
|
|
||||||
{
|
{
|
||||||
$this->assertStringStartsWith('Mozilla/', VideoDownload::getUA());
|
$this->download = new VideoDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test listExtractors funtion
|
* Test listExtractors function
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testListExtractors()
|
public function testListExtractors()
|
||||||
{
|
{
|
||||||
$extractors = VideoDownload::listExtractors();
|
$extractors = $this->download->listExtractors();
|
||||||
$this->assertContains('youtube', $extractors);
|
$this->assertContains('youtube', $extractors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +52,10 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
*/
|
*/
|
||||||
public function testGetURL($url, $format)
|
public function testGetURL($url, $format, $filename, $domain)
|
||||||
{
|
{
|
||||||
$videoURL = VideoDownload::getURL($url, $format);
|
$videoURL = $this->download->getURL($url, $format);
|
||||||
$this->assertArrayHasKey('success', $videoURL);
|
$this->assertContains($domain, $videoURL);
|
||||||
$this->assertArrayHasKey('url', $videoURL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +69,7 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testGetURLError($url)
|
public function testGetURLError($url)
|
||||||
{
|
{
|
||||||
$videoURL = VideoDownload::getURL($url);
|
$this->download->getURL($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,16 +82,19 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
return array(
|
return array(
|
||||||
array(
|
array(
|
||||||
'https://www.youtube.com/watch?v=M7IpKCZ47pU', null,
|
'https://www.youtube.com/watch?v=M7IpKCZ47pU', null,
|
||||||
"It's Not Me, It's You - Hearts Under Fire-M7IpKCZ47pU.mp4"
|
"It's Not Me, It's You - Hearts Under Fire-M7IpKCZ47pU.mp4",
|
||||||
|
'googlevideo.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'https://www.youtube.com/watch?v=RJJ6FCAXvKg', 22,
|
'https://www.youtube.com/watch?v=RJJ6FCAXvKg', 22,
|
||||||
"'Heart Attack' - Demi Lovato ".
|
"'Heart Attack' - Demi Lovato ".
|
||||||
"(Sam Tsui & Against The Current)-RJJ6FCAXvKg.mp4"
|
"(Sam Tsui & Against The Current)-RJJ6FCAXvKg.mp4",
|
||||||
|
'googlevideo.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'https://vimeo.com/24195442', null,
|
'https://vimeo.com/24195442', null,
|
||||||
"Carving the Mountains-24195442.mp4"
|
"Carving the Mountains-24195442.mp4",
|
||||||
|
'vimeocdn.com'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -112,22 +111,6 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test getFilename function
|
|
||||||
*
|
|
||||||
* @param string $url URL
|
|
||||||
* @param string $format Format
|
|
||||||
* @param string $result Expected filename
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @dataProvider URLProvider
|
|
||||||
*/
|
|
||||||
public function testGetFilename($url, $format, $result)
|
|
||||||
{
|
|
||||||
$filename = VideoDownload::getFilename($url, $format);
|
|
||||||
$this->assertEquals($filename, $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getJSON function
|
* Test getJSON function
|
||||||
*
|
*
|
||||||
|
@ -139,7 +122,7 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testGetJSON($url, $format)
|
public function testGetJSON($url, $format)
|
||||||
{
|
{
|
||||||
$info = VideoDownload::getJSON($url, $format);
|
$info = $this->download->getJSON($url, $format);
|
||||||
$this->assertObjectHasAttribute('webpage_url', $info);
|
$this->assertObjectHasAttribute('webpage_url', $info);
|
||||||
$this->assertObjectHasAttribute('url', $info);
|
$this->assertObjectHasAttribute('url', $info);
|
||||||
$this->assertObjectHasAttribute('ext', $info);
|
$this->assertObjectHasAttribute('ext', $info);
|
||||||
|
@ -159,6 +142,6 @@ class VideoDownloadTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testGetJSONError($url)
|
public function testGetJSONError($url)
|
||||||
{
|
{
|
||||||
$videoURL = VideoDownload::getJSON($url);
|
$videoURL = $this->download->getJSON($url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|