4
I have a php script that will receive upload videos and I would like to convert these videos using ffmpeg.
I created a python script that takes parameters from php and calls ffmpeg to do the conversion.
index php.
<?php
$data = array('filePath' => 'video.mov');
$result = shell_exec('/usr/bin/python /home/fernando/Workspace/lab1/public_html/converter.py ' . escapeshellarg(json_encode($data)));
convert py.
#!/usr/bin/env python
import os, sys, json, subprocess, string, random
class Converter():
WORK_DIR = '/home/fernando/Workspace/lab1/public_html'
DESTINATION_DIR = '/home/fernando/Workspace/lab1/public_html/videos/'
NEW_AUDIO = 'audio.mp3'
def __init__(self, data):
try:
os.chdir(self.WORK_DIR)
self.arg = data
except:
print "ERROR"
sys.exit(1)
def generateId():
return ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase ) for _ in range(12))
def convertVideo(self, type):
convertedFileName = self.DESTINATION_DIR + self.generateId() + '.' + type
typesDic = {
'mp4': ['/usr/bin/ffmpeg', '-loglevel', 'quiet', '-i', self.arg['filePath'], '-i', self.NEW_AUDIO, '-map', '0:0', '-map', '1', '-shortest', '-codec', 'copy', convertedFileName, '-y'],
'ogv': ['/usr/bin/ffmpeg', '-loglevel', 'quiet', '-i', self.arg['filePath'], '-i', self.NEW_AUDIO, '-map', '0:0', '-map', '1', '-shortest', '-vcodec', 'libtheora', '-acodec', 'libvorbis', convertedFileName, '-y']
}
sp = subprocess.Popen(typesDic[type], shell=True)
out, err = sp.communicate()
if err:
return {'status': 'error'}
return {'status': 'success', 'filename': convertedFileName}
data = json.loads(sys.argv[1])
c = Converter(data)
print c.convertVideo('mp4')
print c.convertVideo('ogv')
These codes are working the way I need them, but only if I call them
via command line.
Ex: $ php index.php
or: $ ./converter.py '{"fileName": "video.avi"}'
If I access via browser, which was my main intention, it does not work.
I wonder what’s wrong?
It is possible to do this via browser?
Would have a better approach?
Edited:
Exit from apache log:
Use -h to get full help or, Even Better, run 'man ffmpeg' ffmpeg version 1.2.6-7:1.2.6-1~trusty1 Copyright (c) 2000-2014 the Ffmpeg Developers built on Apr 26 2014 18:52:58 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1) Configuration: -Arch=amd64 --disable-stripping --enable-enable-avresample --enable-pthreads --enable-Runtime-cpudetect --extra-version='7:1.2.6-1~trusty1' -libdir=/usr/lib/x86_64-linux-gnu --prefix=/usr --enable-bzlib --enable-libdc1394 --enable-libfreetype --enable-frei0r --enable-gnutls --enable-libgsm --enable-libmp3lame --enable-enable-librtmp --enable-libopencv --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-vaapi --enable-vdpau --enable-libvorbis --enable-libvpx --enable-zlib --enable-gpl --enable-postproc --enable-libcdio --enable-x11grab --enable-libx264 --shlibdir=/usr/lib/x86_64-linux-gnu --enable-Shared --disable-Static libavutil 52. 18.100 / 52. 18.100 libavcodec 54. 92.100 / 54. 92.100 libavformat 54. 63.104 / 54. 63.104 libavdevice 53. 5.103 / 53. 5.103 libavfilter 3. 42.103 / 3. 42.103 libswscale 2. 2.100 / 2. 2.100 libswresample 0. 17.102 / 0. 17.102 libpostproc 52. 2.100 / 52. 2.100 Hyper fast Audio and Video Output: ffmpeg [options] [infile options] -i infile]... {[outfile options] outfile}
You know why it doesn’t work? Did you check the logs or something? My suspicion is that although your ordinary user has access to this file, the Apache user (or whatever webserver you are using) you may not. Another possibility is that PHP is running on
safe_mode
in the webserver, but not when you invoke via command line. Check the error logs, should have some additional information that helps explain the problem.– mgibsonbr
I looked in the logs. It is printing the same message ffmpeg prints when it is invoked without any parameter. I edited the question by adding the log output
– lfalmeida
What about the final string sent to the shell? Have you tried copying the string that the python script runs directly in the S.O.shell? It seems that the apache log output indicates that ffmpeg did not understand the arguments passed.
– Thomas
The PHP call from Python seems right. The Python script too, and although it depends more than I would like the current folder (first you call
os.chdir
, then callPopen
without specifying acwd
) he yet seems correct... I suggest just before calling the ffmpeg print two things in the output/log: 1) the current folder (os.getcwd()
) and 2) the command to be passed toPopen
. By the way, to documentation recommends that when callingPopen
withshell=True
you pass the args as string.– mgibsonbr
Nice @mgibsonbr, thanks for the tips. I removed the shell=True parameter, which the documentation also says can open security loopholes. I will eliminate chdir always working with absolute paths.
– lfalmeida
@Thomas, I made a print in the python script of the command it is running and manually circled directly in the shell. That’s correct.
– lfalmeida
@Luísfernandodealmeida As you already have an absolute path at hand, just join with your file -
os.path.join(WORK_DIR, self.arg['filePath'])
. I just don’t know if it’s going to work out, because despite everything your code still seems correct... And you came to see if the Apache user is allowed to access your file?– mgibsonbr
Finally... it was really permissions. Although the target directories and scripts were with the correct permissions, ffmpeg was not allowed to read the input files of the video and audio. Now it worked! I put it on my test server (http://codefield.ml/) Success! Thank you all for your help.
– lfalmeida
My problem has been solved, I am new here and I would like to know if I need to answer my own question or can I leave it as it is, only with the comments.
– lfalmeida
Answer, it may help more people in the future.
– Thomas
Tried to print the result on the web and run directly in the shell to see the return of '/usr/bin/python /home/Fernando/Workspace/lab1/public_html/converter.py ' . escapeshellarg(json_encode($date));
– Hiago Souza
Sometimes everything is ok, it may be some problem in escapeshellarg(json_encode($data))!!!
– Hiago Souza