以下是对代码进行的优化:

  1. 使用列表推导式获取视频文件列表,避免使用循环和判断语句;

  2. 将文件大小的单位换算过程封装成一个函数,提高代码的复用性;

  3. 将 mediainfo 命令的参数和输出格式封装成一个字典,提高代码的可读性;

  4. 将解析输出结果的代码封装成一个函数,提高代码的复用性;

  5. 将处理多音轨的代码封装成一个函数,提高代码的复用性;

  6. 优化时长取整的代码,使用数值计算代替字符串计算,提高代码的效率;

  7. 使用 f-string 代替字符串拼接,提高代码的可读性;

  8. 将输出文件信息的代码封装成一个函数,提高代码的复用性。

以下是优化后的代码:

import os
import re
import subprocess
import math

# 视频格式
supported_formats = ['.mp4', '.avi', '.mkv', '.wmv', '.mov', '.flv', '.m2ts', '.ts', '.rm', '.rmvb',
                     '.vob', '.3gp', '.webm', '.hdmov', '.mp4v', '.mpv4', '.divx', '.xvid', '.f4v',
                     '.mpeg', '.asf', '.asx', '.m2t']
# 视频文件夹
video_folder = '/home/115/up'
# 正则表达式匹配码率数据中的空格
pattern = re.compile(r'(\d+)\s+(\d+)')
# mediainfo 命令参数和输出格式
mediainfo_args = {
    'video': '--Inform=Video;%Format%|%Width%x%Height%|%BitRate/String%|%FrameRate%|%Duration/String3%',
    'audio': '--Inform=Audio;%BitRate/String%|%SamplingRate/String%|%Language/String%'
}

def get_video_files(folder):
    '''获取视频文件列表'''
    video_files = [os.path.join(root, file) for root, dirs, files in os.walk(folder) for file in files
                   for format in supported_formats if file.endswith(format)]
    return video_files

def convert_size(size):
    '''文件大小单位换算'''
    units = ['B', 'KiB', 'MiB', 'GiB']
    i = 0
    while size >= 1024 and i < len(units) - 1:
        size /= 1024
        i += 1
    size_str = f'{size:.2f} {units[i]}'
    return size_str

def parse_mediainfo_output(output):
    '''解析 mediainfo 输出结果'''
    info = output.strip().split('|')
    return info

def parse_audio_info(audio_info):
    '''处理多音轨情况'''
    audio_bitrate = []
    audio_sampling_rate = []
    audio_lang = []
    for i in range(len(audio_info) // 3):
        audio_bitrate.append(audio_info[i * 3])
        audio_sampling_rate.append(audio_info[i * 3 + 1])
        audio_lang.append(audio_info[i * 3 + 2])
    return audio_bitrate, audio_sampling_rate, audio_lang

def format_duration(duration):
    '''格式化视频时长'''
    h, m, s = map(int, duration.split(':'))
    duration_minutes = h * 60 + m + math.ceil(s / 60)
    duration_str = f'{h}:{m:02d}:{s:02d}'
    return duration_str, duration_minutes

def format_file_info(file_name, size_str, duration_str, video_info, audio_info):
    '''格式化文件信息'''
    video_format, resolution, bitrate, framerate, duration_minutes = video_info
    audio_bitrate, audio_sampling_rate, audio_lang = audio_info
    ratio = round(duration_minutes / size * 1000000000, 2)
    info_str = f'{file_name}, {size_str}, {duration_str}, {resolution}, {bitrate}, {framerate}, {' / '.join(audio_lang)}, {ratio}'
    return info_str

# 获取视频文件列表
video_files = get_video_files(video_folder)

# 遍历所有视频文件
for video_file in video_files:
    # 获取文件名
    file_name = os.path.basename(video_file)

    # 获取文件大小并进行单位换算
    size = os.path.getsize(video_file)
    size_str = convert_size(size)

    # 使用 mediainfo 获取视频信息 / 音频信息
    video_output = subprocess.run(['mediainfo', mediainfo_args['video'], video_file], stdout=subprocess.PIPE).stdout.decode()
    audio_output = subprocess.run(['mediainfo', mediainfo_args['audio'], video_file], stdout=subprocess.PIPE).stdout.decode()

    # 解析输出结果
    video_info = parse_mediainfo_output(video_output)
    audio_info = parse_mediainfo_output(audio_output)
    audio_info = parse_audio_info(audio_info)

    # 格式化视频时长
    duration_str, duration_minutes = format_duration(video_info[4])

    # 使用正则表达式替换码率数据中第一个数字和第二个数字之间的空格
    bitrate = re.sub(pattern, r'\1\2', video_info[2])

    # 获取帧率
    try:
        framerate = float(video_info[3])
    except ValueError:
        framerate = None

    # 格式化文件信息
    info_str = format_file_info(file_name, size_str, duration_str, video_info[1:5], audio_info)

    # 打印文件信息
    print(info_str)
Python 代码优化:提高视频文件信息提取效率

原文地址: https://www.cveoy.top/t/topic/mHka 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录