You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本批量转换H264至MP4崩溃,求循环转换或拆分方案

问题根源与修复方案

你的脚本崩溃的核心问题是全局文件列表只初始化一次,没有动态更新:

  • 开头定义的files、clip_show都是脚本启动时的静态快照,删除h264文件后,files里仍保留已被删除的文件路径,下次调用max(files, ...)时就会触发"找不到文件"的错误。
  • Show_Clips依赖的clip_show也是旧列表,转换后的mp4不会被加载到预览中。

不需要拆分脚本,只需要修改函数逻辑,让它们每次执行时获取最新的文件状态,同时实现批量转换所有h264文件的功能:

修改后的完整代码

from moviepy.editor import *
import glob
import os.path
import subprocess
from time import sleep

# 仅定义路径常量,不存储静态文件列表
FOLDER_PATH = r'/home/pi/Halloween/Recordings'
H264_PATTERN = os.path.join(FOLDER_PATH, '*.h264')
MP4_PATTERN = os.path.join(FOLDER_PATH, '*.mp4')


def Convert_All_Files():
    # 循环处理直到所有h264文件转换完成
    while True:
        # 每次循环重新获取最新的h264文件列表
        h264_files = glob.glob(H264_PATTERN)
        if not h264_files:
            print('没有待转换的h264文件')
            break
        
        # 按创建时间取最新的文件(和原逻辑保持一致)
        latest_clip = max(h264_files, key=os.path.getctime)
        mp4_path = latest_clip + '.mp4'
        
        print(f'开始转换: {latest_clip} -> {mp4_path}')
        # 调用ffmpeg并检查转换结果,减少冗余输出
        result = subprocess.run(['ffmpeg', '-hide_banner', '-loglevel', 'error', '-i', latest_clip, mp4_path])
        if result.returncode == 0:
            os.remove(latest_clip)
            print('转换完成并删除原文件')
        else:
            print(f'转换失败,返回码: {result.returncode}')
            break  # 转换失败时退出循环,避免死循环


def Show_Clips():
    # 每次预览前重新获取并排序所有文件
    all_files = sorted(glob.iglob(os.path.join(FOLDER_PATH, '*')), key=os.path.getctime)
    
    # 检查文件数量是否足够生成预览网格
    if len(all_files) < 6:
        print('文件数量不足,无法生成预览')
        sleep(1)
        return
    
    clips = []
    # 取最近的6个mp4文件(跳过未转换的h264)
    for i in range(1, 7):
        file_path = all_files[-i]
        if file_path.endswith('.h264'):
            continue
        try:
            clip = VideoFileClip(file_path).subclip(0, 1).margin(3)
            clips.append(clip)
        except Exception as e:
            print(f'加载文件失败 {file_path}: {e}')
            continue
    
    if len(clips) < 6:
        print('可用的mp4文件不足6个')
        sleep(1)
        return
    
    # 组合预览网格
    combined = clips_array([[clips[0], clips[1], clips[2]],
                            [clips[3], clips[4], clips[5]]])
    
    combined.preview(audio=False, fps=25)
    # 预览结束后关闭所有clip,释放系统资源
    for clip in clips:
        clip.close()
    sleep(1)


if __name__ == '__main__':
    while True:
        try:
            Convert_All_Files()
            Show_Clips()
        except KeyboardInterrupt:
            print('用户中断程序')
            break

关键修改说明

  1. 动态获取文件列表:两个函数每次执行时都会重新调用glob获取最新的文件状态,避免访问已删除的路径。
  2. 批量转换逻辑:Convert_All_Files内部通过while循环,自动处理所有h264文件直到没有剩余。
  3. 鲁棒性增强:添加了文件数量检查、异常捕获,避免因文件不足或加载失败崩溃;预览结束后主动关闭clip,防止内存泄漏。
  4. 输出优化:给ffmpeg添加参数减少冗余输出,同时检查转换返回码,方便排查失败原因。

内容的提问来源于stack exchange,提问作者Wessie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:13:09