Using ffmpeg with Python 2.7

2019-03-27 21:42发布

问题:

I have been trying to install pyffmpeg in Python 2.7 unsuccessfully. I found a package for Python 2.6, but I can't get it to work. So, I have been mulling around with 2.7. I've seen previous post from others on this site, but they have not helped. Does anyone have experience with this. Ultimately, I want to develop an wxPython app that converts video formats. Thanks

Code that I ultimately wrote that worked for me (very rudimentary, but it works ....):

import wx
import os
import sys
import time
import datetime
from wx.lib.delayedresult import startWorker



class dConvert(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'd-Converter', size=(500, 310))
        panel = wx.Panel(self, wx.ID_ANY)#Creates a panel over the widget
        toolbar = self.CreateToolBar()
        toolbar.Realize()

        #Setup Menu
        #Setting up Menu
        menuFile = wx.Menu()
        menuFile.Append(1, "&About...")
        menuFile.AppendSeparator()
        menuFile.Append(2, "E&xit")
        menuBar = wx.MenuBar()
        menuBar.Append(menuFile, "&File")

        panel.SetBackgroundColour('WHITE')

        menu2 = wx.Menu()
        menu2.Append(5, "&.mpg to dvd", ".mpg to dvd")
        menu2.AppendSeparator()
        menu2.Append(wx.NewId(), "&Options...", "Options...")
        menuBar.Append(menu2, "&DVD")


        menu3 = wx.Menu()
        menu3.Append(7, "&Audio/Video Trim")
        #menu3.AppendSeparator()
        menuBar.Append(menu3, "Media")

        self.SetMenuBar(menuBar)
        self.Bind(wx.EVT_MENU, self.OnAbout, id=1)
        self.Bind(wx.EVT_MENU, self.OnQuit, id=2)
        self.Bind(wx.EVT_MENU, self.OnDVD, id=5)
        self.Bind(wx.EVT_MENU, self.OnMedia, id=7)

        #Add icon to frame
        iconFile = "dconverter_image.jpg"
        icon1 = wx.Icon(iconFile, wx.BITMAP_TYPE_JPEG)
        self.SetIcon(icon1)


        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText("Convert Audio & Video")
        self.statusbar.SetFieldsCount(3)
        self.statusbar.SetStatusWidths([200, -2, -2])



        #Panel Text
        font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        font2 = wx.Font(7, wx.DEFAULT, wx.NORMAL, wx.BOLD)

        directory = wx.StaticText(panel, -1, 'Path: c:\\ffmpeg\\bin', (300, 13))
        directory.SetFont(font2)

        convertfile = wx.StaticText(panel, -1, 'File:', (270, 53))
        convertfile.SetFont(font)

        convertfile2 = wx.StaticText(panel, -1, 'Format:', (245, 83))
        convertfile2.SetFont(font)

        convertfile3 = wx.StaticText(panel, -1, 'Quality:', (244, 113))
        convertfile3.SetFont(font)

        convertfile4 = wx.StaticText(panel, -1, 'Presets:', (239, 143))
        convertfile4.SetFont(font)

        image_file = 'cd_rom.gif'
        bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        panel.bitmap1 = wx.StaticBitmap(panel, -1, bmp1, (50, 30))



        self.formats1 = []


        #Select Media path    
        os.chdir("c:\\ffmpeg\\bin")
        wrkdir = os.getcwd()
        filelist = os.listdir(wrkdir)
        #self.formats1 = []

        for filename in filelist:
            (head, filename) = os.path.split(filename)
            if filename.endswith(".avi") or filename.endswith(".mp4") or filename.endswith(".mpg") or filename.endswith(".m4A") or filename.endswith(".MTS") or filename.endswith(".flv") or filename.endswith(".mov") or filename.endswith(".mpeg4") or filename.endswith(".mpeg") or filename.endswith(".mpg2") or filename.endswith(".mkv") or filename.endswith(".m4v") or filename.endswith(".wav") or filename.endswith(".mp3"):
            self.formats1.append(filename)


        self.format_combo1=wx.ComboBox(panel, size=(140, -1),value='Select Media', choices=self.formats1, style=wx.CB_DROPDOWN, pos=(300,50)) 
        self.Bind(wx.EVT_COMBOBOX, self.fileFormats, self.format_combo1)


        #Media Formats
        self.formats2 = ['Select Format', '.avi','.mpeg','.mp4','.flv','.mov','.m4a','.m4v','.mkv','.mpeg4','.mpg','.mpg2','.mp3','.ogg','.wav','.wma']

        self.format_combo2=wx.ComboBox(panel, size=(100, -1),value='Select Format', choices=self.formats2, style=wx.CB_SORT, pos=(300,81))

        #Media Quality
        self.formats3 = ['-sameq','-qmax']
        self.format_combo3=wx.ComboBox(panel, size=(100, -1),value='Select Quality', choices=self.formats3, style=wx.CB_DROPDOWN, pos=(300,111))



        #-qmax settings
        self.formats4 = ['1','2','3','4','5','6','7','8']
        self.format_combo4=wx.ComboBox(panel, size=(30, -1),value='0', choices=self.formats4, style=wx.CB_DROPDOWN, pos=(405,111))
        self.format_combo4.Disable()


        #Media Quality
        self.formats5 = ['Select Preset','video to mp3']
        self.format_combo5=wx.ComboBox(panel, size=(100, -1),value='Select Preset', choices=self.formats5, style=wx.CB_DROPDOWN, pos=(300,141))

        #Bit rate
        self.formats6 = ['128000', '160000', '180000', '192000']
        self.format_combo6=wx.ComboBox(panel, size=(47, -1),value='k/bs', choices=self.formats6, style=wx.CB_DROPDOWN, pos=(405,141))
        self.format_combo6.Disable()






        #Convert Button
        self.button = wx.Button(panel, label="Convert", pos=(300, 171), size=(80, 20))
        self.Bind(wx.EVT_BUTTON, self.convertButton, self.button)

        #Abort Button
        self.button2 = wx.Button(panel, label="Abort", pos=(385, 171), size=(80, 20))
        self.Bind(wx.EVT_BUTTON, self.OnAbortButton, self.button2)
        self.button2.Disable()

        #Refresh Button
        self.button3 = wx.Button(panel, label="Refresh", pos=(215, 171), size=(80, 20))
        self.Bind(wx.EVT_BUTTON, self.file_refresh, self.button3)


        #ComboBox Event
        self.Bind(wx.EVT_COMBOBOX, self.OncomboBox, self.format_combo3)
        self.Bind(wx.EVT_COMBOBOX, self.OncomboBox2, self.format_combo5)
        self.Bind(wx.EVT_COMBOBOX, self.OncomboBox3, self.format_combo2)



    def file_refresh(self, e):
        self.format_combo1.Clear()
        os.chdir("c:\\ffmpeg\\bin")
        wrkdir = os.getcwd()
        filelist = os.listdir(wrkdir)
        for m_files in filelist:
            if m_files.endswith(".avi") or m_files.endswith(".mp4") or m_files.endswith(".mpg") or m_files.endswith(".m4A") or m_files.endswith(".MTS") or m_files.endswith(".flv") or m_files.endswith(".mov") or m_files.endswith(".mpeg4") or m_files.endswith(".mpeg") or m_files.endswith(".mpg2") or m_files.endswith(".mkv") or m_files.endswith(".m4v") or m_files.endswith(".wav") or m_files.endswith(".mp3"):
            self.format_combo1.Append(m_files)



    def file_rename(self, f_name):
        ts = time.time()
        #Capture readable timestamp
        st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H-%M-%S')
        os.chdir("c:\\ffmpeg\\bin")
        wrkdir = os.getcwd()

        #get file extenstion from original file
        #fileName, fileExtension = os.path.splitext(wrkdir + '\\' + f_name)

        #add file extension to timestamp
        new_file = st 

        return new_file



    def fileFormats(self, e):
        myFormats = {'audio': ('Select Format', '.m4a', '.mp3', '.ogg', '.wav', '.wma'), 'video': ('Select Format', '.avi', '.flv', '.mkv', '.m4v', '.mov', '.mpg', '.mpg2', '.mpeg4', '.mp4', '.mpeg')}
        bad_file = ['Media not supported']
        myFile = self.format_combo1.GetValue()
        f_exten = (x for x in myFormats['audio'] + myFormats['video'] if myFile.endswith(x))
    extension = f_exten.next()

        if extension in myFormats['audio']:
            self.format_combo2.SetItems(myFormats['audio'])

        elif extension in myFormats['video']:
            self.format_combo2.SetItems(myFormats['video'])
        else:
            self.format_combo2.SetItems(bad_file)


    def OnQuit(self, event):
        self.Close(True)

    def OnAbout(self, event):
        wx.MessageBox("d-Converter 1.0\n\n Developer: D.Monroe\n\nCopyright 2012",
                "About d-Converter", wx.OK | wx.ICON_INFORMATION, self)


    def OncomboBox(self, e):
        quality=self.format_combo3.GetValue()
        if quality == '-qmax':
            self.format_combo4.Enable()

        else:
            self.format_combo4.Disable()



    def OncomboBox2(self, e):
        quality=self.format_combo5.GetValue()
        if quality != 'Select Preset':
            self.format_combo1.Enable()
            self.format_combo2.Disable()
            self.format_combo3.Disable()
            self.format_combo4.Disable()
            self.format_combo6.Enable()

        elif quality == 'Select Preset':
            self.format_combo1.Enable()
            self.format_combo2.Enable()
            self.format_combo3.Enable()
            self.format_combo4.Disable()
            self.format_combo5.Enable()
            self.format_combo6.Disable()

        elif quality == 'video to mp3':
            self.format_combo6.Enable()
            self.format_combo2.Disable()
            self.format_combo3.Disable()
            self.format_combo4.Disable()

    def OncomboBox3(self, e):
        v_format=self.format_combo2.GetValue()
        if v_format != 'Select Format':
            self.format_combo1.Enable()
            self.format_combo2.Enable()
            self.format_combo3.Enable()
            self.format_combo4.Enable()
            self.format_combo5.Disable()
            self.format_combo6.Disable()

        elif v_format == 'Select Format':
            self.format_combo1.Enable()
            self.format_combo2.Enable()
            self.format_combo3.Enable()
            self.format_combo4.Disable()
            self.format_combo5.Enable()
            self.format_combo6.Disable()





    def OnMedia(self, e):
        pass

    def OnDVD(self, e):
        """ Select a directory to search"""
        os.chdir("c:\\ffmpeg\\bin")
        wrkdir = os.getcwd()
        filelist = os.listdir(wrkdir)
        progdir = 'c:\\ffmpeg\\bin\\ffmpeg.exe' + ' -i '
        prog_dir = ' -target '
        progdir3 = '-dvd -ac 2 '
        vid_format = '.mpg'


        sampleList = []
        for filename in filelist:
           (head, filename) = os.path.split(filename)
           if filename.endswith(".avi") or filename.endswith(".flv") or filename.endswith(".mpeg") or filename.endswith(".mp4") or filename.endswith(".mov") or filename.endswith(".mpg2"):
            sampleList.append(filename)

        dlg = wx.SingleChoiceDialog(
               self, "Files in c:\\ffmpeg\\bin", 'Select video to convert',
           sampleList,
           wx.CHOICEDLG_STYLE
           )

        if dlg.ShowModal() == wx.ID_OK:
            cur_item = dlg.GetStringSelection()
            s_string = cur_item
            #f_string = self.file_rename(s_string)
            f_string = s_string.replace(' ', '')





        dlg.Destroy()


        dlg2 = wx.SingleChoiceDialog(
               self, "Files in c:\\ffmpeg\\bin", 'Select video standard ',
           ["pal", "ntsc"],
           wx.CHOICEDLG_STYLE
           )

        if dlg2.ShowModal() == wx.ID_OK:
            cur_item2 = dlg2.GetStringSelection()
            s_string2 = cur_item2
            self.button.Disable()
            self.button2.Enable()
            self.format_combo1.Disable()
            self.format_combo2.Disable()
            self.format_combo3.Disable()
            self.format_combo4.Disable()
            self.format_combo5.Disable()
            self.format_combo6.Disable()
            startWorker(self.LongTaskDone, self.LongTask4, wargs=(progdir, wrkdir, prog_dir, progdir3, f_string, s_string2, vid_format))


        dlg2.Destroy()






    def convertButton(self, e):
        unit1 = self.format_combo1.GetValue()
        unit2 = self.format_combo2.GetValue()
        unit3 = self.format_combo3.GetValue()
        unit4 = None
        unit5 = self.format_combo5.GetValue()
        bitRate = self.format_combo6.GetValue()
        unit6 = bitRate
        if unit3 == '-qmax':
            unit4 = self.format_combo4.GetValue()
        else:
            pass

        os.chdir("c:\\ffmpeg\\bin")
        wrkdir = os.getcwd()

        newfile = unit1



        #stripped = os.path.splitext(newfile)[0] # Updated 9/26/2013 to strip extension.
        #stripped = newfile.strip('mpeg3kaviovfl4w2c.') #Strips the extension from the original file name
        stripped = self.file_rename(newfile)

        #os.rename(newfile, newfile_f)



        progname='c:\\ffmpeg\\bin\\ffmpeg.exe' + ' -i '

        preset1_a='-vn -ar 44100 -ac 2 -ab'
        preset1_b='-f mp3 '
        preset_mp3='.mp3'







         if (unit1 == 'Select Media' or unit1 == ''):
                    amsg = wx.MessageDialog(None, 'You must select a media file!', 'Media Converter', wx.ICON_INFORMATION)
                    amsg.ShowModal()
                    amsg.Destroy()



         elif (unit1 != 'Select Media' or unit1 != '') and (unit5 == 'Select Preset'):

             if (unit2 == 'Select Format' or unit2 == ''):
                amsg = wx.MessageDialog(None, 'You must select a format', 'Media Converter', wx.ICON_INFORMATION)
                amsg.ShowModal()
                amsg.Destroy()

                self.format_combo3.Enable()
                self.format_combo4.Enable()
                self.format_combo5.Enable()

            else:
                pass

            if (unit3 == 'Select Quality' or unit3 == ''):
                amsg = wx.MessageDialog(None, 'You must select quality', 'Media Converter', wx.ICON_INFORMATION)
                amsg.ShowModal()
                amsg.Destroy()


            elif (unit3 == '-qmax'):
                if (unit4 == '0' or unit4 == ''):
                    amsg = wx.MessageDialog(None, 'You must select number between 1-8.', 'Media Converter', wx.ICON_INFORMATION)
                    amsg.ShowModal()
                    amsg.Destroy()
                else:
                    self.button.Disable()
                    self.button2.Enable()
                    pass

            else:
                self.button.Disable()
                self.button2.Enable()
                self.format_combo1.Disable()
                self.format_combo2.Disable()
                self.format_combo3.Disable()
                self.format_combo4.Disable()
                startWorker(self.LongTaskDone, self.LongTask, wargs=(progname,wrkdir,unit1,unit3,stripped,unit2))





        elif (unit1 != 'Select Media' or unit1 != '') and (unit5 == 'video to mp3'):
            if unit6 == 'k/bs' or unit6 == None:
                amsg = wx.MessageDialog(None, 'You must select a bit rate.', 'Media Converter', wx.ICON_INFORMATION)
                amsg.ShowModal()
                amsg.Destroy()

            else:
                self.button.Disable()
                self.button2.Enable()
                self.format_combo1.Disable()
                self.format_combo2.Disable()
                self.format_combo3.Disable()
                self.format_combo4.Disable()
                self.format_combo5.Disable()
                self.format_combo6.Disable()
                startWorker(self.LongTaskDone, self.LongTask3, wargs=(progname, wrkdir, unit1, preset1_a, unit6, preset1_b, stripped, preset_mp3))











    def LongTask(self, progname, wrkdir, unit1, unit3, stripped, unit2):
        convert_file1 = progname + wrkdir + '\\' + unit1 + ' ' + unit3 + ' ' + stripped + unit2
        self.statusbar.SetStatusText("Converting: " + unit1 + "...")
        os.system(convert_file1)
        print convert_file1





    def LongTask2(self, progname, wrkdir, unit1, unit3, unit4, stripped, unit2):
        convert_file2 = progname + wrkdir + '\\' + unit1 + ' ' + unit3 + ' ' + unit4 + ' ' + stripped + unit2
        self.statusbar.SetStatusText("Converting: " + unit1 + "...")
        os.system(convert_file2)


    def LongTask3(self, progname, wrkdir, unit1, preset1_a, unit6, preset1_b, stripped, preset_mp3):
        convert_file3 = progname + wrkdir + '\\' + unit1 + ' ' + preset1_a + ' ' + unit6 + ' ' + preset1_b + stripped + preset_mp3
        self.statusbar.SetStatusText("Converting: " + unit1 + "...")
        os.system(convert_file3)

    def LongTask4(self, progdir, wrkdir, prog_dir, progdir3, f_string, s_string2, vid_format):
        #convert_file4 = progdir + wrkdir + '\\' + s_string + prog_dir + s_string2 + progdir3 + s_string.strip('mpegaviw24ofl.') + vid_format
        convert_file4 = progdir + f_string + prog_dir + s_string2 + progdir3 + f_string.strip('mpegaviw24ofl.') + vid_format
        self.statusbar.SetStatusText("Converting: " + f_string + "...")
        os.system(convert_file4)
        print convert_file4



    def LongTaskDone(self, result):
        r = result.get()
        if r:
            amsg = wx.MessageDialog(None, 'Aborted!', 'Media Converter', wx.ICON_INFORMATION)
            self.statusbar.SetStatusText("Convert Aborted ...")
            amsg.ShowModal()
            amsg.Destroy()
            self.LongTask.terminate()
        else:
            self.statusbar.SetStatusText("Done ...")
            emsg = wx.MessageDialog(None, 'Finished Converting!', 'Media Converter', wx.ICON_INFORMATION)
            emsg.ShowModal()
            emsg.Destroy()
            self.format_combo1.Enable()
            self.format_combo2.Enable()
            self.format_combo3.Enable()
            self.format_combo5.Enable()
            self.format_combo4.Disable()
            self.format_combo6.Disable()
            self.button.Enable()
            self.button2.Disable()
            self.shouldAbort = False
        """self.progress_bar.SetValue(0)
        self.progress_bar.Hide()"""



    def OnAbortButton(self, e):
        endprogram = 'c:\\Windows\\System32\\taskkill /IM cmd.exe'
        os.system(endprogram)
        self.format_combo1.Enable()
        self.format_combo2.Enable()
        self.format_combo3.Enable()
        self.format_combo5.Enable()
        self.button.Enable()




if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = dConvert()
    frame.SetSizeHints(500,310,500,310)
    frame.Show()
    app.MainLoop()

回答1:

Since this has no proper answer, I'd like to form one. Unfortunately pyffmpeg wrapper was not able to perform video encoding. So as a solution I suggest you some alternative python wrappers which is capable of our need to encode the videos.

  • Python Video Converter
  • FFmpegWrapper
  • FFVideo

Apart from these you can use full FFmpeg functionality by using python subprocess module to execute full FFmpeg commands. Also with that you can create your own wrapper if you need to. Here Zulko describes a nice way of using subprocess with FFmpeg. Sometimes you will get some confusing events like this when using subprocess. But always there is a solution!

Hope this helps some one with same problem using pyffmpeg to encode videos!