Python3 处理 WMV 视频报错 'not enough values to unpack' 错误解决方法
Python3 处理 WMV 视频报错 'not enough values to unpack' 错误解决方法
在使用 Python3 处理 WMV 视频时,可能会遇到 'not enough values to unpack (expected 3, got 1)' 错误。该错误通常发生在使用 mediainfo 获取视频信息,并使用正则表达式处理码率数据时。
错误原因
错误的原因在于代码中的一行:bitrate = re.sub(pattern, r'\1\2', video_info[2])。这里使用了正则表达式将码率数据中第一个数字和第二个数字之间的空格替换成了空串,但是有些视频的码率数据只有一个数字,这样就会导致 not enough values to unpack (expected 3, got 1) 错误。
解决方法
为了避免该错误,需要判断码率数据中是否包含空格,如果不包含就不需要进行替换。
# 判断码率数据中是否包含空格,如果包含就进行替换
if ' ' in video_info[2]:
bitrate = re.sub(pattern, r'\1\2', video_info[2])
else:
bitrate = video_info[2]
修改后的代码
以下是修改后的完整代码,包括错误处理和进度打印功能:
import os
import re
import subprocess
import openpyxl
import math
from openpyxl.styles import Font, PatternFill, Alignment
# 视频格式
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 = input('请输入文件夹路径:')
# 输出Excel路径
excel_folder = '.'
# 输出Excel文件名
excel_file = 'video_info.xlsx'
# 正则表达式匹配码率数据中的空格
pattern = re.compile(r'(\d+)\s+(\d+)')
# 创建Excel文件
wb = openpyxl.Workbook()
ws = wb.active
ws.title = 'Video Info'
# 获取视频文件列表(包括子目录)
video_files = []
for root, dirs, files in os.walk(video_folder):
for file in files:
for format in supported_formats:
if file.endswith(format):
video_files.append(os.path.join(root, file))
break
# 锁定表头
ws.freeze_panes = 'A2'
# 设置表头样式
header_font = Font(bold=True, color='800080') # 紫色
header_fill = PatternFill('solid', fgColor='C5E0B4')
header_alignment = Alignment(horizontal='center', vertical='center')
headers = ['文件名', '文件路径', '格式', '大小', '时长', '分辨率', '码率', '帧率', '音频码率', '音频采样率', '音频语言', '压缩比率']
for col, header in enumerate(headers, start=1):
cell = ws.cell(row=1, column=col, value=header)
cell.font = header_font
cell.fill = header_fill
cell.alignment = header_alignment
# 处理失败文件个数
failed_count = 0
# 遍历所有视频文件
success_count = 0
row = 2 # 从第二行开始写入数据
for video_file in video_files:
try:
# 获取文件名
file_name = os.path.basename(video_file)
# 获取文件大小并进行单位换算
size = os.path.getsize(video_file)
if size < 1024:
size_str = f'{size} B'
elif size < 1024 * 1024:
size_str = f'{size / 1024:.2f} KiB'
elif size < 1024 * 1024 * 1024:
size_str = f'{size / 1024 / 1024:.2f} MiB'
else:
size_str = f'{size / 1024 / 1024 / 1024:.2f} GiB'
# 使用mediainfo获取视频信息 / 音频信息
video_result = subprocess.run(['mediainfo', '--Inform=Video;%Format%|%Width%x%Height%|%BitRate/String%|%FrameRate%|%Duration/String3%', video_file], stdout=subprocess.PIPE)
video_output = video_result.stdout.decode().strip()
audio_result = subprocess.run(['mediainfo', '--Inform=Audio;%BitRate/String%|%SamplingRate/String%|%Language/String%', video_file], stdout=subprocess.PIPE)
audio_output = audio_result.stdout.decode().strip()
# 解析输出结果
video_info = video_output.split('|')
audio_info = audio_output.split('|')
# 处理多音轨情况
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])
# 时长取整
duration = video_info[4].split('.')[0]
h, m, s = duration.split(':')
duration = f'{h}:{m}:{str(s).zfill(2)}'
# 以分钟计算的时长 2
duration_minutes = int(h) * 60 + int(m) + math.ceil(float(s)) / 60
# 计算压缩比率
ratio = round(duration_minutes / size * 1000000000, 2)
# 判断码率数据中是否包含空格,如果包含就进行替换
if ' ' in video_info[2]:
bitrate = re.sub(pattern, r'\1\2', video_info[2])
else:
bitrate = video_info[2]
# 写入Excel文件
ws.cell(row=row, column=1, value=file_name)
ws.cell(row=row, column=2, value=os.path.dirname(video_file)) # 写入文件夹路径
ws.cell(row=row, column=3, value=video_info[0])
ws.cell(row=row, column=4, value=size_str)
ws.cell(row=row, column=5, value=duration)
ws.cell(row=row, column=6, value=video_info[1])
ws.cell(row=row, column=7, value=bitrate)
ws.cell(row=row, column=8, value=video_info[3])
ws.cell(row=row, column=9, value=' / '.join(audio_bitrate))
ws.cell(row=row, column=10, value=' / '.join(audio_sampling_rate))
ws.cell(row=row, column=11, value=' / '.join(audio_lang))
ws.cell(row=row, column=12, value=ratio)
# 打印进度
print(f'已处理 {success_count+1}/{len(video_files)} 共计', end='\r')
success_count += 1
row += 1
except Exception as e:
# 处理失败,跳过并打印文件名
failed_count += 1
print(f'处理文件 {file_name} 时失败:{e}')
# 将失败的文件写入到err.txt
with open('err.txt', 'a') as f:
f.write(f'{file_name}\n')
continue
# 总计处理文件数
total_count = len(video_files)
# 调整L列左对齐
l_col = ws['L']
for cell in l_col:
cell.alignment = Alignment(horizontal='left') # 左对齐
# 固定列宽
for col in ws.columns:
col_letter = col[0].column_letter
if col_letter not in ['']: # 不固定文件夹路径、格式、音频语言列的宽度
ws.column_dimensions[col_letter].width = 11
# 保存Excel文件
if not os.path.exists(excel_folder):
os.makedirs(excel_folder)
excel_file_path = os.path.join(excel_folder, excel_file)
wb.save(excel_file_path)
# 打印处理失败文件个数和总计处理文件数
print(f'已完成,处理成功 {success_count} 个文件,处理失败 {failed_count} 个文件,视频信息已保存到 {excel_file_path}')
通过以上修改,代码可以正确处理各种码率数据的 WMV 视频,并避免 'not enough values to unpack' 错误。
原文地址: http://www.cveoy.top/t/topic/mE0K 著作权归作者所有。请勿转载和采集!