2013-05-15 49 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