1

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

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,我找不到将 ffmpeg 用于 3.3 的教程。我的 ffmpeg 在我的 PATH 上设置为“ffmpeg64”。

谢谢!

4

1 回答 1

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上,但没有其他方法可以从该代码行中获取该错误。CreateProcess如果你愿意,你可以查一下。

这有三个常见的原因:

  1. 您曾经在特定的 cmd.exe 会话(DOS 提示符)中SET进行修改PATH,但是您在不同的 DOS 提示符下运行代码,或者运行 GUI 代码,或者由于某些其他原因有不同的会话。
  2. 您已经使用控制面板PATH为您的用户进行了修改,但是您正在以不同的用户身份运行 Python 脚本(例如,作为 WSGI 服务的一部分)。
  3. 你根本没有修改PATH;您依赖于您已cd进入与 , 相同的目录这一​​事实ffmpeg64,并且在 Windows 中.是默认的。PATH

作为旁注,这是:

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

… 是相同的:

newFilePath = fileLoc[:-4]

…除了它更难阅读,更不健壮(如果错误少于 4 个字符,它将引发异常fileLoc),并且更慢且更容易出错。

但实际上,如果你想剥离一个扩展,你也不想要. 如果你有foobar.mpeg,你真的想把它变成foobar..mp4吗?使用该os.path模块来调整路径:

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')
于 2013-05-16T00:00:07.957 回答