Calling python script via a php script accessed by the browser

Asked

Viewed 1,863 times

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.

  • 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

  • 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.

  • 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 call Popen without specifying a cwd) 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 to Popen. By the way, to documentation recommends that when calling Popen with shell=True you pass the args as string.

  • 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.

  • @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.

  • @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?

  • 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.

  • 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.

  • Answer, it may help more people in the future.

  • 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));

  • Sometimes everything is ok, it may be some problem in escapeshellarg(json_encode($data))!!!

Show 7 more comments

1 answer

2


Finally solved. It was really permissions. Although the target directories of the files and scripts were with the correct permissions, ffmpeg was not allowed to read the input files of the video and audio. After changing the permissions of the input files to ffmpeg, it worked smoothly.

Thank you all for the tips.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.