Remove dependency on curl (fixes #105)

avconv/ffmpeg now downloads the video directly when converting
This commit is contained in:
Pierre Rudloff 2017-04-24 19:16:38 +02:00
parent b9aad26803
commit b80b9c7b2e
7 changed files with 34 additions and 72 deletions

5
FAQ.md
View File

@ -15,7 +15,6 @@ 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
@ -31,10 +30,10 @@ convert: true
avconv: path/to/avconv
```
You will also need to install `avconv` and `curl` on your server:
You will also need to install `avconv` on your server:
```bash
sudo apt-get install libav-tools curl
sudo apt-get install libav-tools
```
## How do I deploy Alltube on Heroku?

View File

@ -122,13 +122,13 @@ server {
## Other dependencies
You need [avconv](https://libav.org/avconv.html), [rtmpdump](http://rtmpdump.mplayerhq.hu/) and [curl](https://curl.haxx.se/) in order to enable conversions.
You need [avconv](https://libav.org/avconv.html) and [rtmpdump](http://rtmpdump.mplayerhq.hu/) in order to enable conversions.
If you don't want to enable conversions, you can disable it in `config.yml`.
On Debian-based systems:
```bash
sudo apt-get install libav-tools rtmpdump curl
sudo apt-get install libav-tools rtmpdump
```
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).

View File

@ -61,20 +61,6 @@ class Config
*/
public $rtmpdump = 'vendor/bin/rtmpdump';
/**
* curl binary path.
*
* @var string
*/
public $curl = '/usr/bin/curl';
/**
* curl parameters.
*
* @var array
*/
public $curl_params = [];
/**
* Disable URL rewriting.
*
@ -104,9 +90,7 @@ class Config
* * python: Python binary path
* * avconv: avconv or ffmpeg binary path
* * rtmpdump: rtmpdump binary path
* * curl: curl binary path
* * params: Array of youtube-dl parameters
* * curl_params: Array of curl parameters
* * convert: Enable conversion?
*
* @param array $options Options

View File

@ -98,7 +98,7 @@ class VideoDownload
throw new \Exception($errorOutput);
}
} else {
return $process->getOutput();
return trim($process->getOutput());
}
}
@ -222,31 +222,30 @@ class VideoDownload
}
/**
* Get a process that runs curl in order to download a video.
* Get a process that runs avconv in order to convert a video to MP3.
*
* @param object $video Video object returned by youtube-dl
* @param string $url URL of the video file
*
* @return \Symfony\Component\Process\Process Process
*/
private function getCurlProcess($video)
private function getAvconvMp3Process($url)
{
if (!shell_exec('which '.$this->config->curl)) {
throw(new \Exception('Can\'t find curl'));
if (!shell_exec('which '.$this->config->avconv)) {
throw(new \Exception('Can\'t find avconv or ffmpeg'));
}
$builder = ProcessBuilder::create(
array_merge(
[
$this->config->curl,
'--silent',
'--location',
'--user-agent', $video->http_headers->{'User-Agent'},
$video->url,
],
$this->config->curl_params
)
);
return $builder->getProcess();
return ProcessBuilder::create(
[
$this->config->avconv,
'-v', 'quiet',
//Vimeo needs a correct user-agent
'-user-agent', $this->getProp(null, null, 'dump-user-agent'),
'-i', $url,
'-f', 'mp3',
'-vn',
'pipe:1',
]
);
}
/**
@ -260,40 +259,23 @@ class VideoDownload
*/
public function getAudioStream($url, $format, $password = null)
{
if (!shell_exec('which '.$this->config->avconv)) {
throw(new \Exception('Can\'t find avconv or ffmpeg'));
}
$video = $this->getJSON($url, $format, $password);
if (in_array($video->protocol, ['m3u8', 'm3u8_native'])) {
throw(new \Exception('Conversion of M3U8 files is not supported.'));
}
//Vimeo needs a correct user-agent
ini_set(
'user_agent',
$video->http_headers->{'User-Agent'}
);
$avconvProc = ProcessBuilder::create(
[
$this->config->avconv,
'-v', 'quiet',
'-i', '-',
'-f', 'mp3',
'-vn',
'pipe:1',
]
);
if (parse_url($video->url, PHP_URL_SCHEME) == 'rtmp') {
$process = $this->getRtmpProcess($video);
} else {
$process = $this->getCurlProcess($video);
}
$chain = new Chain($process);
$chain->add('|', $avconvProc);
$chain = new Chain($process);
$chain->add('|', $this->getAvconvMp3Process('-'));
return popen($chain->getProcess()->getCommandLine(), 'r');
return popen($chain->getProcess()->getCommandLine(), 'r');
} else {
$avconvProc = $this->getAvconvMp3Process($video->url);
//dump($avconvProc->getProcess()); die;
return popen($avconvProc->getProcess()->getCommandLine(), 'r');
}
}
/**

View File

@ -5,10 +5,8 @@ params:
- --no-warnings
- --playlist-end
- 1
curl_params:
convert: false
avconv: vendor/bin/ffmpeg
rtmpdump: vendor/bin/rtmpdump
curl: /usr/bin/curl
uglyUrls: false
stream: false

View File

@ -45,7 +45,6 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
public function testGetInstance()
{
$this->assertEquals($this->config->convert, false);
$this->assertInternalType('array', $this->config->curl_params);
$this->assertInternalType('array', $this->config->params);
$this->assertInternalType('string', $this->config->youtubedl);
$this->assertInternalType('string', $this->config->python);

View File

@ -350,11 +350,11 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase
*
* @return void
* @expectedException Exception
* @dataProvider urlProvider
* @dataProvider rtmpUrlProvider
*/
public function testGetAudioStreamCurlError($url, $format)
public function testGetAudioStreamRtmpError($url, $format)
{
$download = new VideoDownload(new Config(['curl'=>'foobar', 'rtmpdump'=>'foobar']));
$download = new VideoDownload(new Config(['rtmpdump'=>'foobar']));
$download->getAudioStream($url, $format);
}