.h264或.264视频文件转化成mp4视频
.h264或.264视频文件转化成mp4视频
.h264(也常写作.264)并非传统意义上包含音频、视频封装的 “完整视频文件格式”(如 MP4、MKV),而是H.264/AVC(Advanced Video Coding,高级视频编码)标准对应的原始视频码流文件格式,仅存储视频编码数据,不包含音频流或容器结构,是多媒体领域应用最广泛的视频编码格式之一。
从技术核心来看,H.264 编码通过帧内预测、帧间预测、熵编码等关键技术,在保证较高视频画质的同时,实现了极高的压缩效率 —— 相比早期的 MPEG-2 编码,在相同画质下可将视频文件体积压缩 50% 以上,这一特性使其成为平衡 “画质” 与 “存储 / 传输成本” 的核心选择。例如,1080P 分辨率的视频经 H.264 编码后,仅需 2-8Mbps 的码率即可呈现清晰画面,既能满足在线视频平台的流畅传输需求,也能减少本地存储占用。
在应用场景上,.h264 格式几乎覆盖了多媒体领域的全场景:在线视频平台(如早期 YouTube、国内短视频平台)的视频转码、安防监控系统的录像存储(占监控视频编码的绝大多数份额)、移动端视频拍摄(部分设备可输出 H.264 原始码流)、视频会议系统的实时传输,以及蓝光光盘、数字电视广播等传统领域,均以 H.264 作为核心编码标准。
不过需注意,.h264 文件因仅含视频码流,无法直接用普通播放器(如 Windows Media Player)播放,需搭配对应的音频文件(如 AAC 格式音频),并封装为 MP4、MKV、TS 等容器格式后才能正常播放;若需直接处理.h264 文件,可通过 FFmpeg、Adobe Premiere 等工具进行解码、转码或封装操作。尽管当前 H.265/HEVC 等更高效的编码标准已逐步推广,但 H.264 凭借成熟的生态、广泛的设备兼容性(几乎所有终端设备都支持解码),仍在各类场景中保持着极高的使用率。
环境配置
需要安装一下FFmpeg
打开https://ffmpeg.org/download.html,下载指定的压缩包
然后向下找到指定文件
将下载好的压缩包放在自己心仪的位置,解压后添加环境变量
验证安装,打开终端,输入
ffmpeg -version
python代码
import os
import subprocess
import argparse
import sysdef check_ffmpeg():"""检查FFmpeg是否已安装并可访问"""try:subprocess.run(['ffmpeg', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)return Trueexcept (subprocess.SubprocessError, FileNotFoundError):return Falsedef convert_file(input_path, output_path, reencode=False, crf=23):"""转换单个.264或.h264文件为MP4参数:input_path: 输入的视频文件路径output_path: 输出的.mp4文件路径reencode: 是否重新编码,默认仅复制流crf: 重新编码时的质量参数,值越小质量越高(0-51)"""try:# 构建FFmpeg命令cmd = ['ffmpeg', '-i', input_path, '-f', 'mp4', '-y']if reencode:# 重新编码,兼容性更好但速度较慢cmd.extend(['-c:v', 'libx264', '-crf', str(crf)])else:# 直接复制流,速度快且无质量损失cmd.extend(['-c:v', 'copy'])cmd.append(output_path)# 执行转换命令result = subprocess.run(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True)if result.returncode != 0:print(f"转换失败: {result.stderr}", file=sys.stderr)return Falsereturn Trueexcept Exception as e:print(f"处理文件时出错 {input_path}: {str(e)}", file=sys.stderr)return Falsedef batch_convert(folder_path, reencode=False, crf=23, overwrite=False):"""批量转换文件夹中的所有.264和.h264文件参数:folder_path: 包含视频文件的文件夹路径reencode: 是否重新编码crf: 重新编码时的质量参数overwrite: 是否覆盖已存在的文件"""if not os.path.isdir(folder_path):print(f"错误: 文件夹 '{folder_path}' 不存在", file=sys.stderr)return 0, 0# 获取所有.264和.h264文件video_files = []for f in os.listdir(folder_path):lower_f = f.lower()if (lower_f.endswith('.264') or lower_f.endswith('.h264')) and os.path.isfile(os.path.join(folder_path, f)):video_files.append(f)if not video_files:print(f"在 '{folder_path}' 中未找到任何.264或.h264文件")return 0, 0success_count = 0fail_count = 0print(f"找到 {len(video_files)} 个视频文件,开始转换...")for i, filename in enumerate(video_files, 1):input_path = os.path.join(folder_path, filename)output_filename = os.path.splitext(filename)[0] + '.mp4'output_path = os.path.join(folder_path, output_filename)# 检查输出文件是否已存在if os.path.exists(output_path) and not overwrite:print(f"({i}/{len(video_files)}) 已存在,跳过: {output_filename}")continueprint(f"({i}/{len(video_files)}) 正在转换: {filename}")if convert_file(input_path, output_path, reencode, crf):success_count += 1print(f"({i}/{len(video_files)}) 转换成功: {output_filename}")else:fail_count += 1print(f"({i}/{len(video_files)}) 转换失败: {filename}")return success_count, fail_countdef main():# 检查FFmpeg是否安装if not check_ffmpeg():print("错误: 未找到FFmpeg。请先安装FFmpeg并确保它在系统PATH中。", file=sys.stderr)print("安装指南: https://ffmpeg.org/download.html", file=sys.stderr)sys.exit(1)# 解析命令行参数parser = argparse.ArgumentParser(description='将.264或.h264文件转换为MP4格式')group = parser.add_mutually_exclusive_group(required=True)group.add_argument('-f', '--file', help='单个.264或.h264文件的路径')group.add_argument('-d', '--directory', help='包含.264或.h264文件的文件夹路径')parser.add_argument('-o', '--output', help='输出文件路径(仅用于单个文件转换)')parser.add_argument('-r', '--reencode', action='store_true',help='强制重新编码视频(默认仅复制流)')parser.add_argument('-c', '--crf', type=int, default=23,help='重新编码时的CRF质量参数(0-51,默认23)')parser.add_argument('-w', '--overwrite', action='store_true',help='覆盖已存在的输出文件')args = parser.parse_args()try:if args.file:# 单个文件转换if not os.path.isfile(args.file):print(f"错误: 文件 '{args.file}' 不存在", file=sys.stderr)sys.exit(1)lower_file = args.file.lower()if not (lower_file.endswith('.264') or lower_file.endswith('.h264')):print(f"错误: '{args.file}' 不是.264或.h264文件", file=sys.stderr)sys.exit(1)# 确定输出路径if args.output:output_path = args.output# 确保输出目录存在output_dir = os.path.dirname(output_path)if output_dir and not os.path.exists(output_dir):os.makedirs(output_dir, exist_ok=True)else:# 默认输出路径:与输入文件同目录,替换扩展名为.mp4output_path = os.path.splitext(args.file)[0] + '.mp4'# 检查输出文件是否已存在if os.path.exists(output_path) and not args.overwrite:print(f"错误: 输出文件 '{output_path}' 已存在。使用 -w 选项覆盖它。", file=sys.stderr)sys.exit(1)print(f"正在转换文件: {args.file}")if convert_file(args.file, output_path, args.reencode, args.crf):print(f"转换成功!输出文件: {output_path}")sys.exit(0)else:print("转换失败", file=sys.stderr)sys.exit(1)elif args.directory:# 批量转换success, fail = batch_convert(args.directory,args.reencode,args.crf,args.overwrite)print("\n批量转换完成")print(f"成功: {success} 个文件")print(f"失败: {fail} 个文件")sys.exit(0 if fail == 0 else 1)except Exception as e:print(f"发生错误: {str(e)}", file=sys.stderr)sys.exit(1)if __name__ == "__main__":main()