Python ImportError while using youtube-dl by php - php

Traceback (most recent call last): File "/usr/bin/youtube-dl", line
3, in import youtube_dl File
"/usr/lib/python2.7/dist-packages/youtube_dl/init.py", line 65, in
from .utils import ( File
"/usr/lib/python2.7/dist-packages/youtube_dl/utils.py", line 18, in
import ssl File "/usr/lib/python2.7/ssl.py", line 61, in import _ssl
#if we can't import it, let the error propagate ImportError: /usr/lib/python2.7/lib-dynload/_ssl.x86_64-linux-gnu.so: symbol
GENERAL_NAME_free, version OPENSSL_1.0.0 not defined in file
libcrypto.so.1.0.0 with link time reference
The Command i used
youtube-dl --max-quality 2180 --write-thumbnail -x --audio-format mp3
-c -o "/home/bahaa/%(id)s.%(ext)s" https://www.youtube.com/watch?v=xFQFMSNZW08&list=RDV-jLo0Ovems
The php code i am using
<?php
$url = 'https://www.youtube.com/watch?v=xFQFMSNZW08&list=RDV-jLo0Ovems';
//escapeshellarg
$string = ('youtube-dl --max-quality 2180 --write-thumbnail -x --audio-format mp3 -c -o "/home/bahaa/%(id)s.%(ext)s" https://www.youtube.com/watch?v=xFQFMSNZW08&list=RDV-jLo0Ovems');
$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' => str_replace("\n", "<br />", $stderr."<hr />"),
'output' => $stdout,
)
);
?>

Hi Finally I got the solution!
Firstly, would you please let me know your server configuration? I'm using XAMPP, in my case, the "Python" and its libs used by Apache are not the same as used by my ubuntu, so I build and install Python3 into /opt/lampp/bin and build openssl by myself. You can download openssl1.0.1 from its website and configure it by "./config shared" to build a .so file.
Next copy the libssl.so* and libcrypto.so* (totally 4 files) into /opt/lampp/lib (this is where LD_LIBRARY_PATH points to) and restart apache now
It works for me, Hope it will help you

Related

How to read binary from pipe in PHP

I'm trying to create a PNG from an SVG using Inkscape. I'm using Linux. the command,
cat in.svg | inkscape -z /dev/stdin -w 800 -h 475 -e /dev/stderr 2> out.png
works fine, but I would rather not write the output files on the server.
My code is,
<?php
$svg_data = file_get_contents('in.svg');
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$pipes = array();
$process = proc_open("inkscape -z /dev/stdin -w 800 -h 475 -e /dev/stderr", $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $svg_data);
fclose($pipes[0]);
$fil_data = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
file_put_contents("out.png", $fil_data);
}
?>
If I change the line,
$process = proc_open("inkscape -z /dev/stdin -w 800 -h 475 -e /dev/stderr", $descriptorspec, $pipes);
to
$process = proc_open("inkscape -z /dev/stdin -w 800 -h 475 -e out.png", $descriptorspec, $pipes);
The correct "out.png" is printed.
The current code writes a file, but the file is corrupted. It seems that it is corrupted from beginning to end, but it is about the right size.
I want the data (out.png) in $fil_data, but I don't want to read it from the disk drive.
Why is out.png corrupted, and how can I make the correct conversion without resorting to writing the disk.
Inkscape was putting some messages to stderr before writing the file. The same thing happened on stdout. The problem was fixed by skipping past the messages. So the line,
$fil_data = stream_get_contents($pipes[2]);
was changed to,
$fil_data = stream_get_contents($pipes[2], -1, 150);
If there is a better way, I would like to see it.

Non ASCII Characters in filename are skipped

The program youtube-dl by itself supports Non ASCII characters in filename, It works flawlessly on my webserver under root user as well as www-data user, but when I try downloading a video using youtube-dl with PHP, the Non ASCII characters are completely skipped.
Eg: Stromae - bâtard will be saved as Stromae - btard.mp4 or البث الحي as .mp4
I am using this code to run the CLI command
function cmd($string) {
$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);
return $stdout;
}
$value = ('youtube-dl https://some.valid/link');
echo cmd($value);
Kindly advise what I should do to fix this issue.
Check your phpinfo(); output for LC_ALL or LC_LANG settings. I suspect it has nothing to do with PHP, but with the shell environment that you're using versus the shell environment your web server is using.
$value = ('LC_ALL=en_US.UTF-8 youtube-dl https://some.valid/link');
echo cmd($value);
By default PHP use ISO-8859-1 charset. Configure PHP to use UTF-8. You can to this by adding
mb_internal_encoding("UTF-8");
At the beggining of your script

Get full error from PDFTK when using PHP exec

I'm using PHP exec() in a script to merge PDF files with PDFTK.
From PHP docs: exec function says the second argument, if provided, will list each line from the console output. All I get is an empty array though.
Example of code being used:
exec(pdftk "file1.pdf" "file2.pdf" Merged_File.pdf, $output = array(), $result);
I can successfully get errors if I run the code in the console, but I'd like for my application to have access to the full text errors.
You are probably looking to get messages from stderr using proc_open. Something like this:
<?php
$cmd = "/path/to/script arguments here";
$cwd = dirname(__FILE__);
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
if ( ($process = proc_open($cmd, $descriptorspec, $pipes, $cwd, null)) !== false )
{
// Standard output
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// Errors
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($process);
}
?>

youtube-dl and php exec

I have installed youtube-dl on my CentOS 6 / Plesk 10 Dedicated server, and via SSH, everything works like a charm !
The thing is I'm trying to write a php script which takes a POST parameter in containing the URL of the video I want to copy to the server, copy it and then process it with ffmpeg.
I thought I would use the exec() function.
I can get an output if I echo the results of youtube-dl --help, but everytime I ask php to execute a command which actually does something with the video, it returns a status of '1', and outputs nothing.
Any ideas on what I'm doing wrong ?
Here is my php code:
<?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));
?>
When I execute $string2, I get status: "0" and "url": [youtube-dl help text lines]
But when I execute $string, nothing happens, I get "status": "1" and nothing else, no video is downloaded. I've tried also a simulation with the "-g" parameter, and variants but as soon as youtube-dl has to fetch the video, it breaks.
Thank you in advance !
EDIT
I edited my code so it looks like this :
<?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));
?>
and the result, which I didn't get yesterday now is :
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"
Which is weird, considering a) that yesterday I got an empty url[], and that b) even if now I get what apparently looks like a normal youtube-dl return, it only contains the 3 first lines, and I cannot see any video file in the specified path... Any ideas ?
exec reads only stdout, so you're missing the error message on stderr, whatever that may be.
Use the following code to get stderr as well:
$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));
Most likely, you don't have permission to write to that directory. To test that theory, check whether
touch /var/www/vhosts/my.virtual.host.net/httpdocs/downloader/downloads/test
works. You can use chmod and chown to change permissions.

Process do not gets a pipe from proc_open. lessc - Dynamic Stylesheet language

Here is a source to lessc software, I think it will be helpfull:
https://github.com/cloudhead/less.js/blob/master/bin/lessc
THE PROBLEM
I use lessc in shell simply:
lessc file.less
and I get a css file output.
I tried to do it by php with proc_open. But when I pipe input file to proc, lessc do not gets it. I have a error (from pipe 1):
"lessc: no input files"
which is equivalent in shell to (parameter is not passed):
lessc
lessc ''
My code:
$descriptorspec = array(
0 => array("file", 'path/to/file/foo.less', "r"),
1 => array("pipe", "w"),
2 => array("file", '/tmp/lessCompiler-errors', "a")
);
$process = proc_open('lessc', $descriptorspec, $pipes);
if (is_resource($process)) {
$contents = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($process);
}
btw. I'm trying avoid using the exec() function.
I will be graceful for any help.
Marcin
I ran into the same problem today, not sure if the solution was valid when you posted the question, but now you can pass '-' as input source to lessc in order to make it read from stdin. So you only have to change one line:
$process = proc_open('lessc -', $descriptorspec, $pipes);
As it took me some time to figure out all the details here is my code snippet:
/* run lessc */
$descriptors = array(
0 => array( 'pipe', 'r' ),
1 => array( 'pipe', 'w' ),
2 => array( 'pipe', 'w' ));
$process = proc_open( 'lessc --no-color -x -', $descriptors, $pipes,
'/web/less', array( 'PATH' => '/usr/local/bin/' ) );
if( !is_resource( $process ) ) {
$this->errorMessage( 'Unable to start lessc' );
exit();
}
/* write generated content */
fwrite( $pipes[0], 'some dynamically generated less code' );
fclose( $pipes[0] );
/* read compiled css */
$css = stream_get_contents( $pipes[1] );
fclose( $pipes[1] );
/* check for errors */
if( $stderr = stream_get_contents( $pipes[2] ) ) {
$this->errorMessage( "lessc error: {$stderr}" );
exit();
}
fclose( $pipes[2] );
proc_close( $process );
/* write back */
$this->write( $css );
I had to set PATH on debian wheezy, because lessc kept complaining: /usr/bin/env: node: No such file or directory, see https://github.com/joyent/node/issues/3911
--no-color supresses escape codes in the error messages
-x compresses the css

Categories