Python实现剪映自动关键帧

1 篇文章 0 订阅
1 篇文章 0 订阅

Python实现剪映自动关键帧

说到做小说推文,咱们最痛苦的就是遇到上百张图片,每个都得挨着打关键帧,鄙人也做了几天小说推文,遇到这样头痛的事情,才萌生出自己写一个打关键帧的软件,如何操作的关键帧。这里和大家分享一下如何操作,让剪映自动关键帧。

免费剪映一键关键帧,音频图片自动对齐

1 首先我们要创建一个草稿,让剪映生成对应的文件

image-20230905143816597

2 随便丢几张图片或者视频进去,然后就可以关闭了

image-20230905144339578

3 找到剪映草稿位置

image-20230905144108629

image-20230905144126217

该文件就是存放剪映草稿的关键文件,咱们打开它

image-20230905144528104

image-20230905144643525

这个就是关键的json了,咱们只需要操作json就能实现关键帧了,现在这个json都是一些初始的东西

image-20230905145026889

咱们再次进入剪映,打上关键帧,再观察新的json有哪些改变

4 分析Json

我在最开始的位置和图片结束的位置打了一个关键帧,结束的位置是放大到百分之120.

image-20230905145422430

image-20230905145445321

操作完成后关闭这个界面,此时json文件已经发生了改变,咱们把那个json文件复制到vscode里进行对比,看看哪里发生了改变

image-20230905145611566

image-20230905150147085

会发现这个节点增加的代码比较多,再segments里,就是关键帧存放的位置。咱们刚才在第一个图片添加了两个关键帧,一个初始帧和一个结束帧。

image-20230905150424891

从这里能分析出来,每一张图片都有一个common_keyframes,打上关键帧之后就在common_keyframes里,咱们把第一张图片的关键帧拿出来分析就行了。

{"cartoon": false,"clip": {"alpha": 1.0,"flip": {"horizontal": false,"vertical": false},"rotation": 0.0,"scale": {"x": 1.2,    # 缩放倍数

​              "y": 1.2		# 缩放倍数

​            },"transform": {   # 动画时间

​              "x": 0.0,"y": 0.0}},"common_keyframes": [{"id": "4B48849D-2828-4ab7-978D-41A624C7B5E9","keyframe_list": [{"curveType": "Line","graphID": "","id": "1C3C22E0-1586-4b73-B4FE-16397DA1EE45","left_control": {"x": 0.0,"y": 0.0},"right_control": {"x": 0.0,"y": 0.0},"time_offset": 0,"values": [1.0]},{"curveType": "Line","graphID": "","id": "97305231-1B66-4ebb-AE96-4987D02C1061","left_control": {"x": 0.0,"y": 0.0},"right_control": {"x": 0.0,"y": 0.0},"time_offset": 5000000,   # 关键帧结束时间

​                  "values": [1.2   # 缩放倍数

​                  ]}],"material_id": "","property_type": "KFTypeScaleX"}],"enable_adjust": true,"enable_color_curves": true,"enable_color_wheels": true,"enable_lut": true,"enable_smart_color_adjust": false,"extra_material_refs": ["27FB9436-AADC-47d0-9EDA-B19444B347CC","9CACE842-4FAF-4330-89D3-17AA4C5DFFA9","0CE6F32F-9D57-455f-9B6A-C3BD8B12B592"],"group_id": "","hdr_settings": {"intensity": 1.0,"mode": 1,"nits": 1000},"id": "F771B787-587A-48ac-A550-1E440341E8AD","intensifies_audio": false,"is_placeholder": false,"is_tone_modify": false,"keyframe_refs": [],"last_nonzero_volume": 1.0,"material_id": "6C5ECA8D-A028-4c72-884D-B34D5600CDFE","render_index": 0,"reverse": false,"source_timerange": {"duration": 5000000,"start": 0},"speed": 1.0,"target_timerange": {"duration": 5000000,"start": 0},"template_id": "","template_scene": "default","track_attribute": 0,"track_render_index": 0,"uniform_scale": {"on": true,"value": 1.0},"visible": true,"volume": 1.0}

重点关注:

        "scale": {

          "x": 1.2,    # 缩放倍数

          "y": 1.2		# 缩放倍数

        },

image-20230905150948126

从这里我们可以看出,有两个values,第一个就是咱们打的第一个关键帧,第二个就是第二个关键帧了。倍数也对得上,从100%到120%,至于time_offset就是这个图片的时间轴了。

image-20230905151201093

咱们从这里获取duration就可以丢到time_offset。

咱们可以代码实操一下。

5 Python代码实现

""""
关键帧,缩放
"""

import os
import json
import uuid


def Amplfy(folder_path, num_value):   # 路劲,放大倍数
    try:
        # 遍历文件夹中的文件
        for filename in os.listdir(folder_path):
            file_path = os.path.join(folder_path, filename)

            # 检查文件是否是名为"draft_content.json"的JSON文件
            if os.path.isfile(file_path) and filename == "draft_content.json":
                try:
                    # 以字节方式打开文件,并指定正确的编码格式
                    with open(file_path, "rb") as file:
                        content = file.read().decode("utf-8")  # 编码
                        json_content = json.loads(content)  # 加载JSON
                        for i in json_content['tracks'][0]['segments']:
                            start_position = i['target_timerange']['start']  # 起始时间
                            duration = i['target_timerange']['duration']  # 动画时间
                            end_position = start_position + i['target_timerange'][
                                'duration']  # 结束时间
                            # 缩放倍数
                            n = int(num_value)
                            n = int(num_value) * 0.01  
                            # 复位
                            scale = {
                                "alpha": 1.0,
                                "flip": {
                                    "horizontal": False,
                                    "vertical": False
                                },
                                "rotation": 0.0,
                                "scale": {
                                    "x": 1.0,
                                    "y": 1.0
                                },
                                "transform": {
                                    "x": 0.0,
                                    "y": 0.0
                                }
                            }
                            data_json = {
                                'id': str(uuid.uuid4()).upper(),
                                'keyframe_list': [
                                    {
                                        'curveType': 'Line', 'graphID': '',
                                        'id': str(uuid.uuid4()).upper(),
                                        'left_control': {'x': 0.0, 'y': 0.0},
                                        'right_control': {'x': 0.0, 'y': 0.0},
                                        'time_offset': 0, 'values': [1.0]
                                    },
                                    {
                                        'curveType': 'Line', 'graphID': '',
                                        'id': str(uuid.uuid4()).upper(),
                                        'left_control': {'x': 0.0, 'y': 0.0}, 'right_control': {'x': 0.0, 'y': 0.0},
                                        'time_offset': duration, 'values': [n]
                                    }
                                ],
                                'material_id': '',
                                'property_type': 'KFTypeScaleX'
                            }
                            data2 = []
                            data2.append(data_json)
                            # 只操作没有关键帧的,不影响其他已有的关键帧
                            if len(i['common_keyframes']) < 1:
                                i['common_keyframes'] = data2
                                i['clip'] = scale

                        # 将修改后的数据保存回原始文件
                        with open(file_path, "w", encoding="utf-8") as file:
                            file.write(json.dumps(json_content, indent=4, ensure_ascii=False))
                            return {'code': 200, 'msg': '处理完成'}
                except FileNotFoundError:
                    return {'code': -1, 'msg': '系统找不到指定的路径'}
                except json.JSONDecodeError:
                    return {'code': -1, 'msg': '无法解析JSON文件'}
    except FileNotFoundError:
        return {'code': -1, 'msg': '系统找不到指定的路径'}

这里就结束了,咱这个只是放大,至于其他的功能,都放在网盘里了,上下自动,左右自动,上下左右自动,实现的方法我和这个差不多,分析json就完事儿了,咱gui不好,只能用Django+vue 写点界面了。文件我会放在网盘里。需要学习和自用的自行下载。再来个完整界面图

在这里插入图片描述

在这里插入图片描述

这里就结束了,咱这个只是放大,至于其他的功能,完整版打包好的软件已经放在文件夹里了。

源码下载地址:https://download.csdn.net/download/a820206256/89046277

下载地址:夸克网盘
链接:https://pan.quark.cn/s/88b050381492
提取码:vpNs

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
python 实现 PC端剪映字幕转换SRT格式工具代码-Python 实现,# -*- coding: utf-8 -*- import getpass import os import json import re def get_time(time_int): # 使用正则表达式处理时间格式化问题 if time_int == 0: return '00:00:00,000' p = re.compile(r'(\d*)(\d{3})\d{3}') pl = p.findall(str(time_int))[0] if pl[0] == '': hms = '00:00:00' else: h = 0 m = 0 s = int(pl[0]) while s >= 60: m += 1 s -= 60 while m >= 60: h += 1 m -= 60 while h >= 24: exit('暂不支持超过24小时的字幕文件转换') hms = ':'.join((str(h).zfill(2), str(m).zfill(2), str(s).zfill(2))) return ','.join((hms, pl[1])) def format_time(start, end): # 拼接时间格式化后的字符串 return ' --> '.join((get_time(start), get_time(end))) def main(): # 取得电脑的用户名 username = getpass.getuser() # 拼接取得json文件夹所在地址 json_root_path = 'C:/Users/' + username + '/AppData/Local/JianyingPro/User Data/Projects/com.lveditor.draft/' # 拿到最后一次打开的json文件(内含字幕信息) if os.path.exists(json_root_path): with open(os.path.join(json_root_path, 'root_draft_meta_info.json'), 'r', encoding='utf-8') as f: json_path = (json.load(f)['all_draft_store'][0]['draft_fold_path']) # 打开json文件并将其转换为srt文件 if os.path.exists(json_path): with open(os.path.join(json_path, 'draft_content.json'), 'r', encoding='utf-8') as f: j = json.load(f) l1 = [] l2 = [] for i in j['tracks'][1]['segments']: start_time = int(i['target_timerange']['start']) end_time = int(i['target_timerange']['start'] + i['target_timerange']['duration']) l1.append(format_time(start_time, end_time)) for i in j['materials']['texts']: l2.append(i['content']) idx = 0 # 可以在此处自定义新建的srt字幕路径及文件名 with open('测试.srt', 'w', encoding='utf-8') as srt: while idx < len(l1):
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值