youtube-dl和php exec

7
我已经在我的CentOS 6 / Plesk 10专用服务器上安装了youtube-dl,并通过SSH,一切都运作得很好!但是我正在尝试编写一个php脚本,该脚本接收一个POST参数,其中包含我想要复制到服务器的视频URL,然后将其复制并使用ffmpeg进行处理。我想使用exec()函数。如果我输出youtube-dl --help结果,我可以得到一个输出,但是每当我请求php执行实际与视频有关的命令时,它都会返回状态'1',并且不输出任何内容。您有任何想法吗?以下是我的php代码:
<?php 
    $result = array();
    $status;
    $url = $_POST['src'];
    $string = 'youtube-dl "'.$url.'" -f 18 -o "/var/www/vhosts/my.virtual.host.net/httpdocs/downloader/downloads/%(id)s.%(ext)s"';
    $string2 = 'youtube-dl --help';
    exec($string, $result, $status);
    echo json_encode(array('status' => $status, 'url_orginal'=>$url, 'url' => $result));
?>

当我执行 $string2 时,我得到状态为“0”和“url”:[youtube-dl帮助文本行]。
但是当我执行 $string 时,什么也没有发生,我得到“status”:“1”,没有其他信息,没有下载视频。我也尝试了带有“-g”参数的模拟和变体,但是一旦youtube-dl必须获取视频,它就会中断。
提前谢谢!
编辑
我编辑了我的代码,所以它看起来像这样:
<?php 
    $result = array();
    $status;
    $url = $_POST['src'];
    $string = 'youtube-dl "'.$url.'" -f 18 -o "/var/www/vhosts/my.virtual.host.net/httpdocs/downloader/downloads/%(id)s.%(ext)s"';
    $string2 = 'youtube-dl --help';
    exec($string, $result, $status);
    echo json_encode(array('status' => $status, 'url_orginal'=>$url, 'url' => $result, 'command' => $string));
?>

现在我得到了昨天没有得到的结果:

command: "youtube-dl "http://www.youtube.com/watch?v=coq9klG41R8" -f 18 -o "/var/www/vhosts/my.virtual.host.net/httpdocs/downloader/downloads/%(id)s.%(ext)s""
status: 1
url: 
    0: "[youtube] Setting language"
    1: "[youtube] coq9klG41R8: Downloading video info webpage"
    2: "[youtube] coq9klG41R8: Extracting video information"
url_orginal: "http://www.youtube.com/watch?v=coq9klG41R8"

这很奇怪,因为a)昨天我得到了一个空的url[],而且b)即使现在我得到了看起来像正常的youtube-dl返回结果,它只包含前三行,我不能在指定路径中看到任何视频文件...有什么想法吗?


你能发布生成下载视频命令字符串的代码吗?(var_dump($string)); - gries
我编辑了我的问题并提供了新的信息,谢谢你的帮助! - Charleshaa
1个回答

10

exec 仅读取标准输出,因此您会错过 stderr 上的错误消息,无论它是什么。

使用以下代码获取 stderr:

$url = 'http://www.youtube.com/watch?v=coq9klG41R8';
$template = '/var/www/vhosts/my.virtual.host.net/httpdocs/downloader/' .
            'downloads/%(id)s.%(ext)s';
$string = ('youtube-dl ' . escapeshellarg($url) . ' -f 18 -o ' .
          escapeshellarg($template));

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w"),  // stderr
);
$process = proc_open($string, $descriptorspec, $pipes);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$ret = proc_close($process);
echo json_encode(array('status' => $ret, 'errors' => $stderr,
                       'url_orginal'=>$url, 'output' => $stdout,
                       'command' => $string));

很可能你没有写入该目录的权限。为了测试这个理论,请检查

touch /var/www/vhosts/my.virtual.host.net/httpdocs/downloader/downloads/test

这里是关于工作的。您可以使用chmodchown更改权限。


非常感谢!实际上该文件夹是可写的,但现在我可以看到错误了。它说“视频格式不可用”,所以我修改了$string,这样它只会告诉我可用的格式:('youtube-dl ' . escapeshellarg($url) . ' -F'),然后它告诉我-F不是有效的参数,但它实际上是有效的,不是吗?顺便说一句,我在ssh终端中尝试了该命令,并按预期获得了可用格式的列表,而第18个格式实际上就在那个列表中。 - Charleshaa
@Charleshaa,这听起来非常奇怪。当您在ssh终端时,您是否登录为php运行的同一用户?此外,在会话和php中,which youtube-dl返回什么?最后,请检查~/.config/youtube-dl.conf在php和ssh会话中是否有区别。 - anon
我在ssh中登录为root,但我认为php不是这种情况。你是对的,which youtube-dl在ssh下作为root返回/usr/local/bin/youtube-dl,而在php中返回/usr/bin/youtube-dl。我猜php使用的youtube-dl已经过时了,但是当我通过ssh更新时,它更新第一个而不是第二个...有什么建议吗?非常感谢。 - Charleshaa
1
实际上现在它可以工作了,我在我的 /usr/bin 中有一个来自2009年的版本,哈哈!我猜仓库没有更新...所以我也安装了最新版本的php,现在它运行得非常好!非常感谢您的帮助,当然还有维护这个惊人工具的辛勤付出!! - Charleshaa
phihag请看一下我的问题,链接为http://stackoverflow.com/questions/31675418/download-mp4-flv-url-link-from-youtube-videoid - Xar-e-ahmer Khan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接