用Python和FFmpeg查找大碼率的視頻文件


用Python和FFmpeg查找大碼率的視頻文件

本文使用Python2.7, 這個工作分兩步

  1. 遍歷目錄下的視頻文件
  2. 用ffprobe獲取是視頻文件的碼率信息

用ffprobe 獲取json格式的視頻信息

用ffprobe.exe是FFmpeg自帶的查看視頻信息的工具。其獲取json格式的信息命令例如以下

ffprobe -v quiet -print_format json -show_format -show_streams -i filename

這個命令會輸出 帶有 streams和format項的json結構

Python讀取json

  1. 用os.popen(strCmd).read() 來獲取命令行的輸出
  2. 用json.loads 解析json, 這個必須加try。否則某些亂碼會導致掛機
import os,re,json
# ffprobe 需放置在 system32, not user's PATH
# 調用ffprobo 獲取信息的json格式
def getJsonString(strFileName):
    strCmd =  'ffprobe -v quiet -print_format json -show_format -show_streams -i "' +  strFileName  + '"'  
    mystring = os.popen(strCmd).read()
    return  mystring

# UnicodeDecodeError: 'utf8' codec can't decode byte 0xc0 in position 57: invalid start byte
filecontent = getJsonString(strFileName)

try:
    js = json.loads(filecontent)
except Exception,e:   
    print Exception,":",e, strFileName 
    return

獲取視頻信息

有時候video項中沒有bit_rate這一項,這時須要從format項中取

iVideoWidth = 0
iVideoHeight = 0
iVideoBitRate = 0
iAllBitRate = 0
strCodecName = ''


for stream in arrStreams:
    if(stream['codec_type'] == 'video'):

        strCodecName = stream['codec_name']
        iVideoWidth = int(stream['width'])
        iVideoHeight = int(stream['height'])

        # h264 可能沒有這一項
        if  'bit_rate'  in stream.keys() :
            iVideoBitRate = int (stream['bit_rate'])

        break


iAllBitRate = int(js['format']['bit_rate'])

print  'CodecName (%s), width(%d), height(%d), video bit_rate(%d), all bit_rate (%d)' % (strCodecName, iVideoWidth, iVideoHeight, iVideoBitRate, iAllBitRate )

獲取目錄里的全部文件名

這個網上比較多,取了一個實現簡單的遞歸版本號

g_fileList = []

def getFiles(path):
    if os.path.exists(path):   
        files = os.listdir(path)
        for f in files :
            subpath=os.path.join(path,f)
            if os.path.isfile(subpath):
                g_fileList.append(subpath)
            else:
                getFiles(subpath) 

過濾視頻文件

# 按擴展名過濾        
def filterExname (fileList, arrExtnames):
    filterList = []
    for strFile in fileList:
        strLowFileName = strFile.lower() # 轉小寫先

        for strExtName in arrExtnames :            
            if strLowFileName.endswith(strExtName) :
                filterList.append(strFile)    

    return filterList

g_fileList = []

# 假設是網絡路徑,能夠先映射到本地, python有可能不支持網絡路徑 \\
getFiles('.')

print 'g_fileList len = ', len(g_fileList)        
arrExtName = ['.mkv', '.rmvb', '.rm', '.wmv', '.avi', '.mp4', '.mov', '.mpg', '.xvid', '.asf', '.mpeg', '.vob', '.3gp', '.flv', '.ts']
arrVideoFiles = filterExname (g_fileList, arrExtName)    

過濾大的碼率文件

# 設置單位像素 比特率 閾值 2.5 - 4.0
PIEXL_RATE_MAX = 3.9

def isLargeBps(iWidth, iHeight, iBitrate):
    # 基准 每像素字節數

    fCurrentBitRatePixel = float(iBitrate) / (iWidth * iHeight)

    print  'isNeedConvert input = ', iWidth, iHeight, iBitrate, fCurrentBitRatePixel
    return (fCurrentBitRatePixel > PIEXL_RATE_MAX)

總結

大致就是這樣,至於輸出batch命令行,輸出csv結果就不必細講了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM