Reputation: 13
The simple way my script runs is the user provides a folder location and a filetype and glob.glob() finds the files with the filetype provided and adds them to a list. It then uses a for loop and goes through the list and converts each video. But it doesn't like when I try to run my ffmpeg command. Any help would be awesome. I'm also using Win 7 64 bit with 64 bit ffmpeg and Python 3.3 Here's the error:
OS Error
Traceback (most recent call last):
File "C:\Python33\lib\subprocess.py", line 1106, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\Workspace\PythonConverter\HTMLandPythonConverter\Converter.py", line 77, in <module>
massConvert(fileNames)
File "C:\Users\user\Workspace\PythonConverter\HTMLandPythonConverter\Converter.py", line 47, in massConvert
convertVideotoNewFormat('.mp4', x)
File "C:\Users\user\Workspace\PythonConverter\HTMLandPythonConverter\Converter.py", line 61, in convertVideotoNewFormat
myFile = subprocess.Popen(ffmpegString)#, stdout=subprocess.PIPE, stderr=subprocess.PIPE
File "C:\Python33\lib\subprocess.py", line 820, in __init__
restore_signals, start_new_session)
File "C:\Python33\lib\subprocess.py", line 1112, in _execute_child
raise WindowsError(*e.args)
FileNotFoundError: [WinError 2] The system cannot find the file specified
Here is my code:
import subprocess
from subprocess import call
import glob
fileNames = []
fileLocation = {}
filetype = {}
def convertString(location):
s = list(location)
for i in range(len(s)):
if s[i] in '\\':
s[i] = '/'
if s[len(s)-1] != '/':
s.append('/')
location = "".join(s)
return location
def convertStringBack(stringTo):
s = list(stringTo)
for i in range(len(s)):
if s[i] in '/':
s[i] = '\\'
stringTo = "".join(s)
return stringTo
def fileTypeTester():
FieldType = '*' + input('What\'s the file type we are converting from?')
typeSplit = list(FieldType)
if typeSplit[1] != '.':
typeSplit.insert(1,'.')
FieldType = "".join(typeSplit)
if FieldType not in ['*.flv','*.kdb']:
print('Not a valid file type')
else:
return FieldType
return None
def massConvert(listOfFiles):
print('Starting Conversion')
for x in listOfFiles:
#x = convertStringBack(x)
print('Converting ' + x + ' to .mp4')
convertVideotoNewFormat('.mp4', x)
print('Finished File Conversion')
def convertVideotoNewFormat(newFormat, fileLoc):
newFilePath = fileLoc[0:len(fileLoc)-4]
ffmpegString = ["ffmpeg64","-i", fileLoc,"-qscale","0","-ar","22050","-vcodec","libx264",newFilePath,newFormat]
try:
subprocess.check_call(newFilePath)
except OSError:
print('OS Error')
except subprocess.CalledProcessError:
print('Subprocess Error')
myFile = subprocess.Popen(ffmpegString)
print(myFile)
#This will replace old HTML flv object tag with new video tag, but it is yet to be implemented
def replaceHTML():
pass
fileLocation = input('What is the path of the files you\'d like to convert?')
fileLocation = convertString(fileLocation)
fileType = fileTypeTester()
fileNames = glob.glob(fileLocation + fileType)
massConvert(fileNames)
I've looked around and most of the tutorials are in 2.7 the code is 3.3 and I can't find a tutorial to use ffmpeg for 3.3. My ffmpeg is set to 'ffmpeg64' on my PATH.
Thanks!
Upvotes: 1
Views: 2391
Reputation: 366213
First:
def convertVideotoNewFormat(newFormat, fileLoc):
newFilePath = fileLoc[0:len(fileLoc)-4]
ffmpegString = ["ffmpeg64","-i", fileLoc,"-qscale","0","-ar","22050","-vcodec","libx264",newFilePath,newFormat]
try:
subprocess.check_call(newFilePath)
except OSError:
print('OS Error')
except subprocess.CalledProcessError:
print('Subprocess Error')
This part cannot possibly do anything useful. The newFilePath
is a path you've made by stripping the last 4 characters off a video file. You can't run the program at that path, because (unless you get very, very unlucky) there is no such problem.
That explains the first OSError
.
For the second error, it's telling you that ffmpeg64
isn't on your PATH
. You say that it is on your PATH
, but there is no other way that you could get that error from that line of code. You can look up what CreateProcess
does if you want.
There are three common reasons for this:
SET
to modify the PATH
in a particular cmd.exe session (DOS prompt), but you're running code in a different DOS prompt, or running GUI code, or for some other reason have a different session.PATH
for your user, but you're running the Python script as a different user (e.g., as part of a WSGI service).PATH
at all; you're relying on the fact that you've cd
'd into the same directory as ffmpeg64
, and .
is on the default PATH
in Windows.As a side note, this:
newFilePath = fileLoc[0:len(fileLoc)-4]
… is the same as:
newFilePath = fileLoc[:-4]
… except that it's harder to read, and less robust (it will raise an exception if fileLoc
is under 4 characters wrong), and slower and easier to get wrong.
But really, if you want to strip off an extension, you don't want either. If you have foobar.mpeg
, do you really want to turn that into foobar..mp4
? Use the os.path
module to munge paths:
newFilePath, ext = os.path.splitext(fileLoc)
While we're at it, you've got some other problems in your code:
myFile = subprocess.Popen(ffmpegString)
print(myFile)
subprocess.Popen
creates a subprocess object, which you are eventually going to have to wait
on. Printing it out won't do anything particularly useful.
If you want to do the conversions one at a time, waiting for each one to finish before doing the next, use check_call
, not Popen
here.
If you want to kick them all off in parallel, return myFile
here, and then do something like this:
children = []
for x in listOfFiles:
print('Converting ' + x + ' to .mp4')
children.append(convertVideotoNewFormat('.mp4', x))
for child in children:
child.wait()
print('Finished File Conversion')
Upvotes: 1