1. 程式人生 > >python調用mediainfo工具批量提取視頻信息

python調用mediainfo工具批量提取視頻信息

true amp over output led pip false 調用 文件絕對路徑

寫了2個腳本,分別是v1版本和v2版本

都是python調用mediainfo工具提取視頻元數據信息

v1版本是使用pycharm中測試運行的,指定了視頻路徑

v2版本是最終交付給運營運行的,會把v2版本打成exe運行

先看v1版本

import os,subprocess,json,re,locale,sys
import xlwt,time,shutil
#獲取當前文件所在絕對目錄路徑
# this_path=os.path.abspath(‘.‘)
# print(‘當前路徑為----‘,this_path)
# dir_path=this_path
#視頻文件所在目錄
dir_path=‘I:\\3分鐘便當‘
# print(os.listdir(this_path))
print(‘---------------------------------‘)
print(‘--------------程序馬上開始----------------‘)
# dir_path=this_path
#定義個列表存放每個文件絕對路徑,便於後期操作
init_list=[]

# dir_path=‘F:\\玩具屋總視頻‘
#創建個方法,統計每個文件路徑,並追加列表中。這裏註釋掉了遞歸,不獲取子目錄了,只獲取dir_path下面的視頻
def get_all_file(dir_path,init_list):
    for file in os.listdir(dir_path):
        # print(file)
        filepath=os.path.join(dir_path,file)
        # print(filepath)
        if os.path.isdir(filepath):
            print(‘遇到子目錄---%s---此版本暫不提取子目錄視頻信息--‘%(filepath))
            time.sleep(2)
            # get_all_file(filepath)
        else:
            if not file.endswith(‘exe‘):
                init_list.append(filepath)
    return init_list
#執行上面方法,把每個文件絕對路徑追加到列表中
file_list=get_all_file(dir_path,init_list)
print("文件讀取完畢-----3秒後開始獲取視頻詳細信息------------")
time.sleep(3)

#定義個方法,獲取單個media文件的元數據,返回為字典數據
#此程序核心是調用了mediainfo工具來提取視頻信息的
def get_media_info(file):
    pname=‘D:\mediainfo_i386\MediaInfo.exe "%s" --Output=JSON‘%(file)
    result=subprocess.Popen(pname,shell=False,stdout=subprocess.PIPE).stdout
    list_std=result.readlines()
    str_tmp=‘‘
    for item in list_std:
        str_tmp+=bytes.decode(item.strip())
    json_data=json.loads(str_tmp)
    return json_data

#定義個方法傳遞字典數據,返回自己想要的字段數據,返回值列表
def get_dict_data(json_data):
    #獲取文件大小
    filesize=json_data[‘media‘][‘track‘][0][‘FileSize‘]
    #獲取碼率
    malv=json_data[‘media‘][‘track‘][0][‘OverallBitRate‘][0:4]
    #獲取播放時長
    duration=json_data[‘media‘][‘track‘][0][‘Duration‘].split(‘.‘)[0]
    #獲取文件類型
    file_format=json_data[‘media‘][‘track‘][0][‘Format‘]
    #獲取幀寬
    samp_width=json_data[‘media‘][‘track‘][1][‘Sampled_Width‘]
    #獲取幀高
    samp_height=json_data[‘media‘][‘track‘][1][‘Sampled_Height‘]
    return [filesize,malv,duration,file_format,samp_width,samp_height]

#定義個方法,獲取文件名,它是key,它的value就是目標列表,返回值是個字典,參數是文件列表
dict_all={}
#定義個日誌存提取失敗視頻文件名
f_fail=open(‘提取失敗日誌.log‘,‘a‘,encoding=‘utf-8‘) # 追加模式
def get_all_dict(file_list,f_fail):
    for file in file_list:
        filename=os.path.split(file)[1]
        print(filename)
        time.sleep(0.1)
        try:
            info_list=get_dict_data(get_media_info(file))
            dict_all[filename]=info_list
        except Exception as e:
            print(filename,‘------提取此文件信息失敗---------‘)
            f_fail.write(filename+‘\r\n‘)
    f_fail.close()


get_all_dict(file_list,f_fail)
# for item in dict_all:
#     print(item,dict_all[item])

#創建一個excel表存放文件路徑信息,第一列是目錄,第二列是文件名
wb = xlwt.Workbook()
sh = wb.add_sheet(‘元數據‘)
#寫第一行
row_count=0
sh.write(row_count,0,"文件名")
sh.write(row_count,1,"文件大小")
sh.write(row_count,2,"碼率")
sh.write(row_count,3,"總時長")
sh.write(row_count,4,"視頻格式")
sh.write(row_count,5,"幀寬")
sh.write(row_count,6,"幀高")

#批量寫入視頻信息
row_count=1
for item in dict_all:
    sh.write(row_count,0,item)
    sh.write(row_count,1,dict_all[item][0])
    sh.write(row_count,2,dict_all[item][1])
    sh.write(row_count,3,dict_all[item][2])
    sh.write(row_count,4,dict_all[item][3])
    sh.write(row_count,5,dict_all[item][4])
    sh.write(row_count,6,dict_all[item][5])
    row_count+=1
#
wb.save("元數據統計.xls")
#

  

在看v2版本

v2版本是對當前目錄下的視頻進行提取

import os,subprocess,json,re,locale,sys
import xlwt,time,shutil
#獲取當前文件所在絕對目錄路徑
this_path=os.path.abspath(‘.‘)
print(‘當前路徑為----‘,this_path)
dir_path=this_path
# print(os.listdir(this_path))
print(‘---------------------------------‘)
print(‘--------------程序馬上開始----------------‘)
# dir_path=this_path
#定義個列表存放每個文件路徑,便於後期操作
init_list=[]
# dir_path=‘I:\\3分鐘便當‘
# dir_path=‘F:\\玩具屋總視頻‘
#創建個方法,統計每個文件路徑,並追加列表中。用到了遞歸,這裏不獲取子目錄了
def get_all_file(dir_path,init_list):
    for file in os.listdir(dir_path):
        # print(file)
        filepath=os.path.join(dir_path,file)
        # print(filepath)
        if os.path.isdir(filepath):
            print(‘遇到子目錄---%s---此版本暫不提取子目錄視頻信息--‘%(filepath))
            time.sleep(2)
            # get_all_file(filepath)
        else:
            if not file.endswith(‘exe‘):
                init_list.append(filepath)
    return init_list
#執行上面方法,把每個文件絕對路徑追加到列表中
file_list=get_all_file(dir_path,init_list)
print("文件讀取完畢-----3秒後開始獲取視頻詳細信息------------")
time.sleep(3)

#定義個方法,獲取單個media文件的元數據,返回為字典數據
def get_media_info(file):
    pname=‘D:\mediainfo_i386\MediaInfo.exe "%s" --Output=JSON‘%(file)
    result=subprocess.Popen(pname,shell=False,stdout=subprocess.PIPE).stdout
    list_std=result.readlines()
    str_tmp=‘‘
    for item in list_std:
        str_tmp+=bytes.decode(item.strip())
    json_data=json.loads(str_tmp)
    return json_data

#定義個方法傳遞字典數據,返回自己想要的字段數據,返回值列表
def get_dict_data(json_data):
    #獲取文件大小
    filesize=json_data[‘media‘][‘track‘][0][‘FileSize‘]
    #獲取碼率
    malv=json_data[‘media‘][‘track‘][0][‘OverallBitRate‘][0:4]
    #獲取播放時長
    duration=json_data[‘media‘][‘track‘][0][‘Duration‘].split(‘.‘)[0]
    #獲取文件類型
    file_format=json_data[‘media‘][‘track‘][0][‘Format‘]
    #獲取幀寬
    samp_width=json_data[‘media‘][‘track‘][1][‘Sampled_Width‘]
    #獲取幀高
    samp_height=json_data[‘media‘][‘track‘][1][‘Sampled_Height‘]
    return [filesize,malv,duration,file_format,samp_width,samp_height]

#定義個方法,獲取文件名,它是key,它的value就是目標列表,返回值是個字典,參數是文件列表
dict_all={}
f_fail=open(‘提取失敗日誌.log‘,‘a‘,encoding=‘utf-8‘) # 追加模式
def get_all_dict(file_list,f_fail):
    for file in file_list:
        filename=os.path.split(file)[1]
        print(filename)
        time.sleep(0.1)
        try:
            info_list=get_dict_data(get_media_info(file))
            dict_all[filename]=info_list
        except Exception as e:
            print(filename,‘------提取此文件信息失敗---------‘)
            f_fail.write(filename+‘\r\n‘)
    f_fail.close()


get_all_dict(file_list,f_fail)
# for item in dict_all:
#     print(item,dict_all[item])

#創建一個excel表存放文件路徑信息,第一列是目錄,第二列是文件名
wb = xlwt.Workbook()
sh = wb.add_sheet(‘元數據‘)
#寫第一行
row_count=0
sh.write(row_count,0,"文件名")
sh.write(row_count,1,"文件大小")
sh.write(row_count,2,"碼率")
sh.write(row_count,3,"總時長")
sh.write(row_count,4,"視頻格式")
sh.write(row_count,5,"幀寬")
sh.write(row_count,6,"幀高")

row_count=1
for item in dict_all:
    sh.write(row_count,0,item)
    sh.write(row_count,1,dict_all[item][0])
    sh.write(row_count,2,dict_all[item][1])
    sh.write(row_count,3,dict_all[item][2])
    sh.write(row_count,4,dict_all[item][3])
    sh.write(row_count,5,dict_all[item][4])
    sh.write(row_count,6,dict_all[item][5])
    row_count+=1
#
wb.save("元數據統計.xls")

  

把v2版本打成exe文件

技術分享圖片

如下路徑下拷貝此exe文件

技術分享圖片

這個程序交付給運營同事即可

測試和驗證部分


使用方式,把程序放在視頻同級目錄下

按照代碼縮寫,如果視頻運行成功:

1、此程序不會對haha目錄進行處理

2、對於無法識別的文件比如abc.123(可能不是視頻文件,或者已經損壞的視頻文件),此程序會記錄日誌,同時程序正常運行不會中斷

3、程序運行之後會有一個失敗日誌.log文件,記錄了提取信息失敗的視頻名,同時把提取成功的視頻文件放在“元數據統計.xls”中

技術分享圖片

測試驗證下

雙擊運行

技術分享圖片

運行結束

技術分享圖片

技術分享圖片

excel表信息

文件大小是字節,如果想顯示為MB或者GB,使用excel表內置的公式即可處理

有很多字段,碼率,時長等。這裏因為運營只需要如下字段,就提取了這些

技術分享圖片

如果把此exe程序交付給運營同事使用,需要把D盤那個mediainfo_i386文件夾一起交給他們,此文件加必須放在D盤

python調用mediainfo工具批量提取視頻信息