1
votes

Hi I'm trying to make a video converter for django with python, I forked django-ffmpeg module which does almost everything I want, except that doesn't catch error if conversion failed.

Basically the module passes to the command line interface the ffmpeg command to make the conversion like this:

/usr/bin/ffmpeg -hide_banner -nostats -i %(input_file)s -target film-dvd %(output_file)

Module uses this method to pass the ffmpeg command to cli and get the output:

def _cli(self, cmd, without_output=False):
    print 'cli'
    if os.name == 'posix':
        import commands
        return commands.getoutput(cmd)
    else:
        import subprocess
        if without_output:
            DEVNULL = open(os.devnull, 'wb')
            subprocess.Popen(cmd, stdout=DEVNULL, stderr=DEVNULL)
        else:
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            return p.stdout.read()

But for example, I you upload an corrupted video file it only returns the ffmpeg message printed on the cli, but nothing is triggered to know that something failed

This is an ffmpeg sample output when conversion failed:

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x237d500] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible! [mov,mp4,m4a,3gp,3g2,mj2 @ 0x237d500] moov atom not found /home/user/PycharmProjects/videotest/media/videos/orig/270f412927f3405aba041265725cdf6b.mp4: Invalid data found when processing input

I was wondering if there's any way to make that an exception and how, so I can handle it easy.

The only option that came to my mind is to search: "Invalid data found when processing input" in the cli output message string but I'm not shure that if this is the best approach. Anyone can help me and guide me with this please.

2

2 Answers

3
votes

You need to check the returncode of the Popen object that you're creating. Check the docs: https://docs.python.org/3/library/subprocess.html#subprocess.Popen

Your code should wait for the subprocess to finish (with wait) & then check the returncode. If the returncode is != 0 then you can raise any exception you want.

3
votes

This is how I implemented it in case it's useful to someone else:

def _cli(self, cmd):
        errors = False
        import subprocess
        try:
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            stdoutdata, stderrdata = p.communicate()
            if p.wait() != 0:
                # Handle error / raise exception
                errors = True
                print "There were some errors"
                return stderrdata, errors
            print 'conversion success '
            return stderrdata, errors
        except OSError as e:
            errors = True
            return e.strerror, errors