2013-05-15 54 views
1

我的脚本运行的用户提供了一个文件夹位置和一个文件类型和glob.glob(最简单的方法),找到该文件所提供的文件类型,并将它们添加到列表中。然后它使用for循环并遍历列表并转换每个视频。但它不喜欢当我尝试运行我的ffmpeg命令。任何帮助都是极好的。我还使用Win 7的64位与64位的ffmpeg和Python 3.3 这里的错误:与Python回溯错误使用时的ffmpeg转换视频

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 

这里是我的代码:

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) 

我环顾四周,并且大多数教程在2.7的代码是3.3​​,我找不到3.3的ffmpeg教程。我的ffmpeg在我的PATH上设置为'ffmpeg64'。

谢谢!

+0

你_sure_那'ffmpeg64'在你的'PATH'? (你确定你看到的DOS提示符中的'PATH'与Python正在看到的PATH是一样的吗?如果你只是在提示符处设置它,它只会影响你的非GUI程序从同一个提示符开始运行。) – abarnert

+0

另外,2.7'子进程'代码几乎在3.3中保持不变(只要你不想传递非ASCII字符作为参数,你不会)。所以,你的教程应该没问题。 – abarnert

回答

1

第一:

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') 

这部分不可能做任何有用的。 newFilePath是您通过从视频文件中删除最后4个字符而创建的路径。你不能在该路径上运行该程序,因为(除非你非常非常不幸),不存在这样的问题。

这解释了第一个OSError


对于第二个错误,它告诉你,ffmpeg64是不是在你的PATH。你说它在你的PATH,但是没有其他的方法可以从that line of code得到那个错误。如果需要,你可以查看CreateProcess

这有三种常见的原因:

  1. 您已经使用SET修改特定的CMD.EXE会话PATH(DOS提示符),但你在不同的DOS提示符下运行代码,或者运行GUI代码,或者由于其他原因有不同的会话。
  2. 您已经使用控制面板中修改PATH您的用户,但你正在运行的Python脚本为不同的用户(例如,作为WSGI服务的一部分)。
  3. 根本没有修改PATH;你依靠,你已经cd倒是到同一目录ffmpeg64,并且.是在Windows中默认PATH的事实。

作为一个方面说明,这一点:

newFilePath = fileLoc[0:len(fileLoc)-4] 

...是一样的:

newFilePath = fileLoc[:-4] 

...但它是难以阅读,并且不太可靠(它会如果fileLoc是4个字符错误,则引发异常),并且速度更慢,更容易出错。

但是的确,如果你想剥离扩展名,你不想要或者。如果你有foobar.mpeg,你真的想把它变成foobar..mp4?使用os.path模块Munge时间路径:

newFilePath, ext = os.path.splitext(fileLoc) 

虽然我们在这,你得在你的代码的一些其他问题:

myFile = subprocess.Popen(ffmpegString) 
print(myFile) 

subprocess.Popen创建一个子对象,你最终将不得不wait。打印出来不会做任何特别有用的事情。

如果您想一次执行一次转换,请在执行下一个操作前等待每个转换完成,请在此处使用check_call而不是Popen

如果你想踢他们全部关闭并行,return myFile这里,然后做这样的事情:

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') 
+0

感谢您帮助我解决问题,我对Python非常感兴趣,并感谢您的帮助。 – TheMickeyNick

+0

我与ffmpeg有同样的问题,我没有命令提示它进入路径,我使用了高级系统设置 - >环境变量,并添加到PATH中'; C:\ ffmpeg \ bin',它在该文件。 [图片1](http://imgur.com/8jUo1qH)和[图片2](http://imgur.com/4BjHKkb) – TheMickeyNick

+0

首先,在图片2中,那里没有一个名为'ffmpeg64'的程序。有一个'ffmpeg',但这不是同一个名字。 – abarnert