Python循环生成嵌套JSON数组问题:视频剪辑帧信息被覆盖
视频编辑APP多剪辑片段JSON生成问题:数据覆盖而非新增对象
问题背景
我们开发的视频编辑APP包含多轨道,每个轨道可容纳单个或多个剪辑片段。需求是提取每个剪辑的起始帧/结束帧等信息生成JSON文件。单剪辑场景下功能正常,但处理多个剪辑时,新剪辑的数据会覆盖之前的剪辑数据,无法在clip_element数组中创建新的JSON对象。
当前错误输出
处理多剪辑时生成的JSON如下(后添加的剪辑覆盖了第一个剪辑的数据):
{ "framesPerSecond": 24, "StartFrame": 1, "lastFrame": 1293, "clip_element": [ { "clip_name": "", "track_info": [ { "start": 1, "first": 1, // 该剪辑开始播放的位置 "last": 1293, // 剪辑结束的帧位置 "hold_last": "0" // 当前未使用 } ], "transitions": "none" // 当前未使用 } ] }
期望输出
当添加多个剪辑时,clip_element数组应新增独立的JSON对象:
{ "framesPerSecond": 24, "StartFrame": 1, "lastFrame": 1293, "clip_element": [ { "clip_name": "", "track_info": [ { "start": 1, "first": 1, // 该剪辑开始播放的位置 "last": 891, // 剪辑结束的帧位置 "hold_last": "0" // 当前未使用 } ], "transitions": "none" // 当前未使用 }, { "clip_name": "", "track_info": [ { "start": 891, "first": 892, // 该剪辑开始播放的位置 "last": 1293, // 剪辑结束的帧位置 "hold_last": "0" // 当前未使用 } ], "transitions": "none" // 当前未使用 } ] }
问题根源
原代码中硬编码指向clip_element[0],每次循环都修改数组的第一个元素,而非创建新的剪辑对象并追加到数组中。关键错误代码片段:
json_data['clip_element'][0]['clip_name'] = track_name json_data['clip_element'][0]['track_info'][0]['start'] = round(start_frame) + 1 json_data['clip_element'][0]['track_info'][0]['first'] = round(start_frame_position) json_data['clip_element'][0]['track_info'][0]['last'] = round(clip_end_frame) json_data['clip_element'][0]['track_info'][0]['hold_last'] = round(clip_end_frame)
修复方案
- 初始化
json_data时,确保clip_element是空数组,而非默认包含一个空对象 - 遍历每个剪辑时,创建新的剪辑字典对象,填充
clip_name、track_info等字段 - 使用
.append()方法将新的剪辑对象添加到clip_element数组中 - 循环结束后统一写入文件,避免每次循环覆盖文件内容
调整后的核心代码片段:
# 初始化基础JSON结构,确保clip_element为空数组 json_data = { "framesPerSecond": fps_num, "StartFrame": 0, "lastFrame": 0, "clip_element": [] } with open("%s-%s.json" % (file_path.replace(".json", ""), track_name), 'w', encoding="utf8") as f: for index, clip in enumerate(clips_on_track, start=1): # 帧计算逻辑保持不变 start_frame = codeToFrames(clip.data.get('start'), fps_num, fps_den) end_frame = codeToFrames(clip.data.get('end'), fps_num, fps_den) start_frame_position = codeToFrames(clip.data.get('position'), fps_num, fps_den) end_frame_position = codeToFrames(clip.data.get('position') + (clip.data.get('end') - clip.data.get('start')), fps_num, fps_den) clip_end_frame = timecodeToFrames(clip.data.get('position') + (clip.data.get('end')), fps_num, fps_den) has_video = clip.data.get("reader", {}).get("has_video", False) if has_video: # 创建新的剪辑对象 new_clip = { "clip_name": track_name, "track_info": { "start": round(start_frame) + 1, "first": round(start_frame_position), "last": round(clip_end_frame), "hold_last": round(clip_end_frame) }, "transition": "none" } # 追加到clip_element数组 json_data['clip_element'].append(new_clip) # 更新全局起始/结束帧(按需调整逻辑) if index == 1: json_data['StartFrame'] = round(start_frame) json_data['lastFrame'] = round(end_frame_position) # 循环结束后统一写入文件 json.dump(json_data, f, indent=4)
修复验证
使用.append()方法后,成功实现多剪辑对象的追加,更新后的JSON输出符合预期:
{ "framesPerSecond": 24, "StartFrame": 1, "lastFrame": 1327, "clip_element": [ { "clip_name": "", "track_info": { "start": 1, "first": 0, "last": 701, "hold_last": 701 }, "transition": "none" }, { "clip_name": "", "track_info": { "start": 1, "first": 626, "last": 1327, "hold_last": 1327 }, "transition": "none" } ] }
内容的提问来源于stack exchange,提问作者Jod
相关产品推荐
相关产品推荐

