Python批量转码案例有哪些?一文掌握高效文件编码转换技巧
目录导读
- 什么是批量转码?为什么需要Python?
- 文本文件批量转码(GBK转UTF-8)
- 视频文件批量转码(使用FFmpeg)
- 图片格式批量转换(PNG转JPG)
- 音频批量转码(MP3转WAV)
- PDF批量转文本/图片
- 常见问题与避坑指南
- 总结与进阶建议
什么是批量转码?为什么需要Python?
批量转码是指将多个文件(如文本、音视频、图片等)从一种编码格式或容器格式批量转换为另一种格式的过程,在日常办公、数据处理、多媒体存档等场景中,经常遇到文件编码不兼容、格式过时或需要统一标准的问题。
Python之所以成为批量转码的首选工具,原因有三:
- 强大的库生态:内置
codecs模块处理文本编码,第三方库如FFmpeg、Pillow、pydub覆盖多领域; - 自动化处理:一行循环代码即可遍历数千个文件;
- 跨平台兼容:Windows/Linux/macOS通用。
常见应用场景:网站迁移需统一UTF-8编码、老视频播放器不支持H.265、摄影后期批量转换RAW预览图等。
案例一:文本文件批量转码(GBK转UTF-8)
需求:某公司历史项目中存在大量GBK编码的.txt文件,需全部转换为UTF-8。
核心代码:
import os
import codecs
def batch_convert_gbk_to_utf8(folder_path):
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.endswith('.txt'):
file_path = os.path.join(root, file)
try:
# 读取GBK内容
with codecs.open(file_path, 'r', encoding='gbk') as f:
content = f.read()
# 写入UTF-8
with codecs.open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"已转换:{file_path}")
except UnicodeDecodeError:
print(f"跳过非GBK文件:{file_path}")
batch_convert_gbk_to_utf8('./source_folder')
关键点:
- 使用
codecs.open指定编码,避免UnicodeDecodeError; os.walk递归遍历子目录;- 异常处理防止转码失败中断流程。
扩展:如需保留原文件备份,可先在转换前复制到_bak目录。
案例二:视频文件批量转码(使用FFmpeg)
需求:将文件夹内所有.avi视频转换为.mp4(H.264编码),同时压缩体积。
前置条件:安装ffmpeg-python库(pip install ffmpeg-python)并确保系统已安装FFmpeg。
代码示例:
import ffmpeg
import os
def batch_convert_video(folder_path):
for file in os.listdir(folder_path):
if file.endswith('.avi'):
input_path = os.path.join(folder_path, file)
output_path = os.path.join(folder_path, file.replace('.avi', '.mp4'))
# 转码参数:视频H.264,音频AAC,降低码率
stream = ffmpeg.input(input_path)
stream = ffmpeg.output(stream, output_path, vcodec='libx264', acodec='aac', video_bitrate='1M')
ffmpeg.run(stream, overwrite_output=True)
print(f"转码完成:{output_path}")
batch_convert_video('./videos')
参数优化:
video_bitrate='1M':控制画质与文件大小平衡;overwrite_output=True:覆盖已有文件避免重复询问。
注意:FFmpeg是命令行工具,ffmpeg-python只是封装了调用逻辑,部分复杂需求(如字幕嵌入)可直接用subprocess调用原生命令。
案例三:图片格式批量转换(PNG转JPG)
需求:设计网站导出的PNG图片透明背景转为白色JPG,并压缩质量。
代码(依赖Pillow库:pip install Pillow):
from PIL import Image
import os
def batch_png_to_jpg(folder_path, quality=85):
for file in os.listdir(folder_path):
if file.lower().endswith('.png'):
img_path = os.path.join(folder_path, file)
try:
img = Image.open(img_path)
# 处理透明通道:填充白色背景
if img.mode == 'RGBA':
background = Image.new('RGB', img.size, (255, 255, 255))
background.paste(img, mask=img.split()[3])
img = background
else:
img = img.convert('RGB')
output_path = os.path.join(folder_path, file.replace('.png', '.jpg'))
img.save(output_path, 'JPEG', quality=quality, optimize=True)
print(f"已转换:{output_path}")
except Exception as e:
print(f"处理失败 {img_path}: {e}")
batch_png_to_jpg('./images')
质控细节:
quality=85:平衡视觉质量与文件体积;optimize=True:启用优化压缩;- 透明背景处理:不处理会导致黑色块。
扩展:可添加--delete-old参数自动删除原PNG。
案例四:音频批量转码(MP3转WAV)
需求:语音识别系统仅支持WAV格式,需将海量MP3文件转换。
代码(安装pydub:pip install pydub,需安装ffmpeg或libav):
from pydub import AudioSegment
import os
def batch_mp3_to_wav(folder_path):
for file in os.listdir(folder_path):
if file.endswith('.mp3'):
sound = AudioSegment.from_mp3(os.path.join(folder_path, file))
output_path = os.path.join(folder_path, file.replace('.mp3', '.wav'))
sound.export(output_path, format="wav")
print(f"转码完成:{output_path}")
batch_mp3_to_wav('./audio')
参数调整:
frame_rate=16000:语音识别常用采样率,加入sound = sound.set_frame_rate(16000);- 批量时注意内存:pydub将音频加载到内存,过大会导致崩溃,建议加批处理上限。
案例五:PDF批量转文本/图片
需求:将大量PDF合同转为可编辑的文本文件,或提取每一页为图片。
文本提取(使用PyMuPDF:pip install PyMuPDF):
import fitz # PyMuPDF的别名
import os
def pdf_to_text(folder_path):
for file in os.listdir(folder_path):
if file.endswith('.pdf'):
doc = fitz.open(os.path.join(folder_path, file))
text = ""
for page in doc:
text += page.get_text()
txt_path = os.path.join(folder_path, file.replace('.pdf', '.txt'))
with open(txt_path, 'w', encoding='utf-8') as f:
f.write(text)
doc.close()
print(f"文本已保存:{txt_path}")
pdf_to_text('./pdfs')
提取图片(每PDF输出一个图片文件夹):
def pdf_to_images(pdf_path, output_dir):
doc = fitz.open(pdf_path)
for page_num in range(doc.page_count):
page = doc[page_num]
pix = page.get_pixmap()
pix.save(f"{output_dir}/page_{page_num+1}.png")
doc.close()
注意:大型PDF可能导致内存占用过高,建议逐页处理。
常见问题与避坑指南
Q1:转码后中文乱码怎么办?
A:确保源文件编码判断正确,可用chardet库自动检测编码:
import chardet
with open('file.txt', 'rb') as f:
result = chardet.detect(f.read())
print(result['encoding'])
Q2:视频转码后音画不同步?
A:常见于参数不匹配,建议保留原始音频流(-acodec copy),仅转换视频编码,或使用FFmpeg内置的同步校正参数-vsync 2。
Q3:批量处理大量文件时内存溢出?
A:逐文件处理(非一次性读入内存),对于音频/视频,考虑分片处理或使用subprocess调用外部工具(如FFmpeg)释放Python内存压力。
Q4:如何批量更改文件名后缀? A:可在转码前统一重命名:
os.rename(old_path, new_path)
或使用pathlib库更简洁。
Q5:转码过程中如何记录错误日志?
A:使用Python标准库logging:
import logging
logging.basicConfig(filename='convert_errors.log', level=logging.ERROR)
try:
# 转码逻辑
except Exception as e:
logging.error(f"文件 {file_path} 转码失败: {e}")
总结与进阶建议
通过以上五个案例,可以看出Python批量转码的核心模式:
- 遍历文件:
os.listdir或os.walk; - 调用编码库:
codecs、ffmpeg-python、Pillow、pydub、PyMuPDF; - 异常处理:确保至少有一个文件失败时不会导致整个脚本终止;
- 输出管理:原文件备份、日志记录、进度条显示(使用
tqdm库)。
进阶建议:
- GUI界面化:用
Tkinter或PyQt5封装成桌面工具,方便非技术人员使用; - 并行处理:使用
multiprocessing或asyncio加速大批量文件处理; - 云存储集成:结合
boto3(AWS S3)或azure-storage-blob,实现云端文件转码; - 调度自动化:配合
cron(Linux)或任务计划程序(Windows)定时执行。
最佳实践:始终在测试目录中先运行脚本,确认无误后再对正式数据操作,善用print()或tqdm查看进度,避免因无响应而误以为死机。
希望这些案例能帮助你高效完成批量转码任务,如果你有特殊的转码需求,欢迎留言讨论。
标签: Python批量转码