On 3 September 2013 05:49, eryksun <eryk...@gmail.com> wrote: > On Mon, Sep 2, 2013 at 10:19 AM, learner404 <learner...@gmail.com> wrote: >> >> I can't understand why the command below works with os.system but not with >> subprocess.Popen (on windows, recording video with FFMPEG.exe) >> >> cmd=('ffmpeg -f dshow -i video="%s" -f dshow -i audio="%s" -q 5 "%s"')% >> (videoinputName, audioinputName, videoFileOutput) >> os.system(cmd) >> *works* >> >> subprocess.Popen(["ffmpeg","-f","dshow","-i",'video="%s"'%videoinputName, >> "-f","dshow","-i",'audio="%s"'%audioinputName,"-q","5", >> "%s"%videoFileOutput]) >> *don't work* >>>> [dshow @ 025984a0] Could not find video device. >>>> video="QuickCam Orbit/Sphere AF": Input/output error > > Popen joins the list into a string, as required by Windows > CreateProcess(). It assumes the tokenizing rules used by Microsoft's C > runtime. If that assumption is wrong, just switch to using a string > instead of a list, with whatever custom quoting is required.
I've previously tried to find documentation that explains how MSVCRT handles this. I didn't find anything as explicit as the explanation in the subprocess docs. For example: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx > I'd first > try it like this: > > args = ['ffmpeg', > '-f', 'dshow', '-i', 'video=%s' % videoinputName, > '-f', 'dshow', '-i', 'audio=%s' % audioinputName, > '-q', '5', videoFileOutput] By the way if you find this kind of thing a little less elegant than the command line string for os.system you can always make a helper function e.g.: >>> import shlex >>> def cmdsplit(cmdline, **kwargs): ... return [a % kwargs for a in shlex.split(cmdline)] ... >>> cmdline = 'ffmpeg -f dshow -i video=%(video)s -f dshow -i audio=%(audio)s >>> -q 5 %(device)s' >>> cmdsplit(cmdline, video="my video.mpg", audio="my audio.wav", device="my >>> cam") ['ffmpeg', '-f', 'dshow', '-i', 'video=my video.mpg', '-f', 'dshow', '-i', 'audio=my audio.wav', '-q', '5', 'my cam'] > > Here's a simple script to print the raw command line, and also sys.argv. > > test.py > > import sys > from ctypes import * > > windll.kernel32.GetCommandLineW.restype = c_wchar_p > > print(windll.kernel32.GetCommandLineW()) I'm pretty sure Python 2.x uses CreateProcessA and GetCommandLineA. No idea about ffmpeg though (and probably makes no difference here)... > print(' '.join(sys.argv)) I'd expect 'print(sys.argv)' to be more informative here. > system() vs Popen(): > > >>> exe = sys.executable > > >>> cmdstr = '%s test.py video="QuickCam Orbit"' % exe > >>> os.system(cmdstr) > C:\Python27\python.exe test.py video="QuickCam Orbit" > test.py video=QuickCam Orbit > 0 > > >>> cmdlst = [exe, 'test.py', 'video="QuickCam Orbit"'] > >>> subprocess.call(cmdlst) > C:\Python27\python.exe test.py "video=\"QuickCam Orbit\"" > test.py video="QuickCam Orbit" > 0 Ah, so subprocess does actually pass the quotes through. Okay that's probably not what's wanted then. It occurs to me that another possibility is if ffmpeg isn't really an .exe on PATH but rather a .bat file or something. In that case os.system or subprocess shell=True would pick it up but subprocess shell=False might not. I say "might" because at least on some version of Windows CreateProcess can run .bat files directly but I've never seen this documented anywhere. Apparently some newer versions of Windows have a "where" command that could find ffmpeg for you. I don't have it on XP though... Oscar _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor