4

I have been trying to run this ffmpeg command from python script to generate video of certain length from a static image but I keep getting No such file or directory error! Here is my code:

import subprocess

def generate_white_vid (duration):
    ffmpeg_create_vid_from_static_img = 'ffmpeg -loop 1 -i /same_path/WhiteBackground.jpg -c:v libx264 -t %f -pix_fmt yuv420p -vf scale=1920:1080 /same_path/white_vid2.mp4' % duration
    print ffmpeg_create_vid_from_static_img
    pp = subprocess.Popen(ffmpeg_create_vid_from_static_img)
    pp.communicate()

generate_white_vid(0.5)

However when I run the same exact command:

ffmpeg -loop 1 -i /same_path/WhiteBackground.jpg -t 0.500000 -pix_fmt yuv420p -vf scale=1920:1080 /same_path/white_vid2.mp4

from the cli, it works just fine. Where am I missing up? Here is the full trace:

Traceback (most recent call last):
  File "gen.py", line 10, in <module>
    generate_white_vid(0.5)
  File "gen.py", line 7, in generate_white_vid
    pp = subprocess.Popen(ffmpeg_create_vid_from_static_img)
  File "/home/ubuntu/anaconda2/lib/python2.7/subprocess.py", line 390, in __init__
    errread, errwrite)
  File "/home/ubuntu/anaconda2/lib/python2.7/subprocess.py", line 1024, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

When I use a list to pass the ffmpeg commands parameters as following ffmpeg_create_vid_from_static_img = ['ffmpeg', '-loop', '1', '-i', '/same_path/WhiteBackground.jpg', '-c:v', 'libx264', '-t', duration, '-pix_fmt', 'yuv420p', '-vf', 'scale=1920:1080', '/same_path/white_vid.mp4'] , I get a type error:

TypeError                                 Traceback (most recent call last)
<ipython-input-137-4a9e12e42310> in <module>()
----> 1 generate_white_vid(0.5)

<ipython-input-136-edfbfc017557> in generate_white_vid(duration)
      3     ffmpeg_create_vid_from_static_img = ['ffmpeg', '-loop', '1', '-i', '/home/ubuntu/matar/multispectral/WhiteBackground.jpg', '-c:v', 'libx264', '-t', duration, '-pix_fmt yuv420p', '-vf', 'scale=1920:1080', '/home/ubuntu/matar/multispectral/white_vid.mp4']
      4     print ffmpeg_create_vid_from_static_img
----> 5     pp = subprocess.Popen(ffmpeg_create_vid_from_static_img)
      6     pp.communicate()

/home/ubuntu/anaconda2/lib/python2.7/subprocess.pyc in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
    388                                 p2cread, p2cwrite,
    389                                 c2pread, c2pwrite,
--> 390                                 errread, errwrite)
    391         except Exception:
    392             # Preserve original exception in case os.close raises.

/home/ubuntu/anaconda2/lib/python2.7/subprocess.pyc in _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, to_close, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite)
   1022                         raise
   1023                 child_exception = pickle.loads(data)
-> 1024                 raise child_exception
   1025 
   1026 

TypeError: execv() arg 2 must contain only strings
6
  • 1
    Maybe missing an argument shell=True for Popen? Commented Nov 23, 2017 at 17:09
  • @etopylight This has ridiculously worked, Thank you a lot. Do you have any idea why? Commented Nov 23, 2017 at 17:20
  • 2
    Since shell=False is default for Popen, you would normally need to construct the command line as a separate list of elements (which is more secure by the way). However, in case when you just want to pass your command as a string, then a mandatory shell=True would be required Commented Nov 23, 2017 at 17:31
  • when I tried passing the command as separate list of element, I got a type error. see above for the full trace stack. Also, would u please add an answer so that I could give u ur deserved credit by accepting it. Thanks Commented Nov 23, 2017 at 17:44
  • 1
    Thanks, added an answer. For the type error however, I think the error message is informing you that your duration is not a string, so you might want to try casting it to a string. Commented Nov 23, 2017 at 17:58

1 Answer 1

3

Since shell=False is the default value for Popen, you would normally need to construct the command line as a separate list of elements (which is more secure by the way).

However, in case when you just want to pass your command as a string, then a mandatory shell=True would be required.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.