使用Python创建剪映草稿,并导入图片和音频放在轨道上,图片对齐音频

剪映创建草稿文件,关键的两个文件,draft_content.json和draft_meta_info.json,只需要创建这两个文件,剪映会自动补全其他文件。

1 创建两个模版,用于初始化数据。

在这里插入图片描述

draft_content_data.json的数据

{
    "canvas_config": {
        "height": 1920,
        "ratio": "original",
        "width": 1920
    },
    "color_space": 0,
    "config": {
        "adjust_max_index": 1,
        "attachment_info": [],
        "combination_max_index": 1,
        "export_range": null,
        "extract_audio_last_index": 1,
        "lyrics_recognition_id": "",
        "lyrics_sync": true,
        "lyrics_taskinfo": [],
        "maintrack_adsorb": true,
        "material_save_mode": 0,
        "original_sound_last_index": 1,
        "record_audio_last_index": 1,
        "sticker_max_index": 1,
        "subtitle_recognition_id": "",
        "subtitle_sync": true,
        "subtitle_taskinfo": [],
        "system_font_list": [],
        "video_mute": false,
        "zoom_info_params": null
    },
    "cover": null,
    "create_time": 0,
    "duration": 20000000,
    "extra_info": null,
    "fps": 30.0,
    "free_render_index_mode_on": false,
    "group_container": null,
    "id": "",
    "keyframe_graph_list": [],
    "keyframes": {
        "adjusts": [],
        "audios": [],
        "effects": [],
        "filters": [],
        "handwrites": [],
        "stickers": [],
        "texts": [],
        "videos": []
    },
    "last_modified_platform": {
        "app_id": 3704,
        "app_source": "lv",
        "app_version": "4.7.2",
        "device_id": "fc871fd0f7df9197856c41e5c14692e3",
        "hard_disk_id": "41242e7a5bd929da250d4f775eb50880",
        "mac_address": "bd3b6e089f498a7037dc279f6ee07f73",
        "os": "windows",
        "os_version": "10.0.22621"
    },
    "materials": {
        "audio_balances": [],
        "audio_effects": [],
        "audio_fades": [],
        "audios": [],
        "beats": [],
        "canvases": [],
        "chromas": [],
        "color_curves": [],
        "digital_humans": [],
        "drafts": [],
        "effects": [],
        "flowers": [],
        "green_screens": [],
        "handwrites": [],
        "hsl": [],
        "images": [],
        "log_color_wheels": [],
        "loudnesses": [],
        "manual_deformations": [],
        "masks": [],
        "material_animations": [],
        "material_colors": [],
        "placeholders": [],
        "plugin_effects": [],
        "primary_color_wheels": [],
        "realtime_denoises": [],
        "shapes": [],
        "smart_crops": [],
        "sound_channel_mappings": [],
        "speeds": [],
        "stickers": [],
        "tail_leaders": [],
        "text_templates": [],
        "texts": [],
        "transitions": [],
        "video_effects": [],
        "video_trackings": [],
        "videos": [],
        "vocal_beautifys": [],
        "vocal_separations": []
    },
    "mutable_config": null,
    "name": "",
    "new_version": "87.0.0",
    "platform": {
        "app_id": 3704,
        "app_source": "lv",
        "app_version": "4.7.2",
        "device_id": "fc871fd0f7df9197856c41e5c14692e3",
        "hard_disk_id": "41242e7a5bd929da250d4f775eb50880",
        "mac_address": "bd3b6e089f498a7037dc279f6ee07f73",
        "os": "windows",
        "os_version": "10.0.22621"
    },
    "relationships": [],
    "render_index_track_mode_on": false,
    "retouch_cover": null,
    "source": "default",
    "static_cover_image_path": "",
    "tracks": [],
    "update_time": 0,
    "version": 360000
}

draft_meta_data.json

{
        "cloud_package_completed_time": "",
        "draft_cloud_capcut_purchase_info": "",
        "draft_cloud_last_action_download": false,
        "draft_cloud_materials": [],
        "draft_cloud_purchase_info": "",
        "draft_cloud_template_id": "",
        "draft_cloud_tutorial_info": "",
        "draft_cloud_videocut_purchase_info": "",
        "draft_cover": "draft_cover.jpg",
        "draft_deeplink_url": "",
        "draft_enterprise_info": {
            "draft_enterprise_extra": "",
            "draft_enterprise_id": "",
            "draft_enterprise_name": "",
            "enterprise_material": []
        },
        "draft_fold_path": "",
        "draft_id": "",
        "draft_is_article_video_draft": false,
        "draft_is_from_deeplink": "false",
        "draft_materials": [
            {
                "type": 0,
                "value": []
            },
            {
                "type": 1,
                "value": []
            },
            {
                "type": 2,
                "value": []
            },
            {
                "type": 3,
                "value": []
            },
            {
                "type": 6,
                "value": []
            },
            {
                "type": 7,
                "value": []
            },
            {
                "type": 8,
                "value": []
            }
        ],
        "draft_materials_copied_info": [],
        "draft_name": "",
        "draft_new_version": "",
        "draft_removable_storage_device": "",
        "draft_root_path": "",
        "draft_segment_extra_info": [],
        "draft_timeline_materials_size_": 0,
        "tm_draft_cloud_completed": "",
        "tm_draft_cloud_modified": 0,
        "tm_draft_create": 0,
        "tm_draft_modified": 0,
        "tm_draft_removed": 0,
        "tm_duration": 0
    }

分析json,在剪映里导入一张图片

draft_content.json的变化,
canvases,
sound_channel_mappings,
speeds,
videos,
vocal_separations
tracks
tracks下的segments

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我添加了4张图片。经过分析。
canvases,
sound_channel_mappings,
speeds,
videos,
vocal_separations
tracks
tracks下的segments键值对都会有添加数据,
注意细节:
sound_channel_mappings,
speeds,
videos,
vocal_separations
tracks下的segments
在添加了图片后,都会在每一个数组里添加4个数据,但是tracks只会创建一个,而tracks下的segments是添加了4个数据。
经过分析这4个数据的id对应情况,
videos的id对应tracks下的segments的material_id
而这4个ID对应
第一个对应materials下的speeds里的id,
第二个对应materials下的canvases里的id
第三个对应materials下的sound_channel_mappings里的id
第三个对应materials下的vocal_separations里的id

在这里插入图片描述
canvases的数据

{
	"album_image": "",
	"blur": 0,
	"color": "",
	"id": "4B6E427A-A0CE-4CB5-8FDD-625D3C46FFD1", // 此ID对应tracks第0个的segments里的extra_material_refs第2个
	"image": "",
	"image_id": "",
	"image_name": "",
	"source_platform": 0,
	"team_id": "",
	"type": "canvas_color"
}

sound_channel_mappings的数据

{
	"audio_channel_mapping": 0,
	"id": "03559466-D479-45D4-ACE8-5C93C295C32C",  // 此id// 此ID对应tracks第0个的segments里的extra_material_refs第3个
	"is_config_open": false,
	"type": "none"
}

speeds的数据

{
	"curve_speed": null,
	"id": "DC6EC53C-3497-46CE-AF3A-61B002016226", // 此id// 此ID对应tracks第0个的segments里的extra_material_refs第1个
	"mode": 0,
	"speed": 1,
	"type": "speed"
}

vocal_separations的数据

{
	"choice": 0,
	"id": "BB3B2A8D-31ED-4AF3-BB2F-389F52FE714D", // 此id// 此ID对应tracks第0个的segments里的extra_material_refs第4个
	"production_path": "",
	"time_range": null,
	"type": "vocal_separation"
}

videos下的数据

{
	"aigc_type": "none",
	"audio_fade": null,
	"cartoon_path": "",
	"category_id": "",
	"category_name": "local",
	"check_flag": 63487,
	"crop": {
	"lower_left_x": 0,
	"lower_left_y": 1,
	"lower_right_x": 1,
	"lower_right_y": 1,
	"upper_left_x": 0,
	"upper_left_y": 0,
	"upper_right_x": 1,
	"upper_right_y": 0
	},
	"crop_ratio": "free",
	"crop_scale": 1,
	"duration": 10800000000,
	"extra_type_option": 0,
	"formula_id": "",
	"freeze": null,
	"gameplay": null,
	"has_audio": false,
	"height": 1080,  // 图片高度
	"id": "13F7F3F1-663C-4F28-8616-489EB3799964",  // 此id对应tracks下的segments的material_id
	"intensifies_audio_path": "",
	"intensifies_path": "",
	"is_ai_generate_content": false,
	"is_unified_beauty_mode": false,
	"local_id": "",
	"local_material_id": "",
	"material_id": "",
	"material_name": "1.png",   // 图片名称
	"material_url": "",
	"matting": {
	"flag": 0,
	"has_use_quick_brush": false,
	"has_use_quick_eraser": false,
	"interactiveTime": [],
	"path": "",
	"strokes": []
	},
	"media_path": "",
	"object_locked": null,
	"origin_material_id": "",
	"path": "C:/Users/lsl/Desktop/tttest/1.png",   // 图片完整路劲
	"picture_from": "none",
	"picture_set_category_id": "",
	"picture_set_category_name": "",
	"request_id": "",
	"reverse_intensifies_path": "",
	"reverse_path": "",
	"smart_motion": null,
	"source": 0,
	"source_platform": 0,
	"stable": {
	"matrix_path": "",
	"stable_level": 0,
	"time_range": {
	"duration": 0,
	"start": 0
	}
	},
	"team_id": "",
	"type": "photo",   // 图片类型
	"video_algorithm": {
	"algorithms": [],
	"deflicker": null,
	"motion_blur_config": null,
	"noise_reduction": null,
	"path": "",
	"quality_enhance": null,
	"time_range": null
	},
	"width": 1080   // 图片高度
}

注意: 只要创建图片只会创建一个tracks而type类型是video,4个图片都在segments里添加数据

{
	"attribute": 0,
	"flag": 0,
	"id": "22820104-5F4C-4EE7-AA66-49181365FB11",  // 唯一ID,随便用uuid生成就行
	"is_default_name": true,
	"name": "",
	"segments": [],
	"type": "video"
}

segments的数据

{
	"cartoon": false,
	"clip": {
	"alpha": 1,
	"flip": {
	"horizontal": false,
	"vertical": false
	},
	"rotation": 0,
	"scale": {
	"x": 1,
	"y": 1
	},
	"transform": {
	"x": 0,
	"y": 0
	}
	},
	"common_keyframes": [],
	"enable_adjust": true,
	"enable_color_curves": true,
	"enable_color_match_adjust": false,
	"enable_color_wheels": true,
	"enable_lut": true,
	"enable_smart_color_adjust": false,
	"extra_material_refs": [
	"DC6EC53C-3497-46CE-AF3A-61B002016226",   // speeds的id
	"4B6E427A-A0CE-4CB5-8FDD-625D3C46FFD1",   // canvases的id
	"03559466-D479-45D4-ACE8-5C93C295C32C",	  // sound_channel_mappings的id
	"BB3B2A8D-31ED-4AF3-BB2F-389F52FE714D"	  // vocal_separations的id
	],
	"group_id": "",
	"hdr_settings": {
	"intensity": 1,
	"mode": 1,
	"nits": 1000
	},
	"id": "BCC33EDD-DB17-4E5F-9949-B1AEC1D94BF0",  // 唯一id 
	"intensifies_audio": false,
	"is_placeholder": false,
	"is_tone_modify": false,
	"keyframe_refs": [],
	"last_nonzero_volume": 1,
	"material_id": "13F7F3F1-663C-4F28-8616-489EB3799964",  //该id对应videos里的id
	"render_index": 0,
	"responsive_layout": {
	"enable": false,
	"horizontal_pos_layout": 0,
	"size_layout": 0,
	"target_follow": "",
	"vertical_pos_layout": 0
	},
	"reverse": false,
	"source_timerange": {
	"duration": 1566666,   // 图片持续时间
	"start": 0
	},
	"speed": 1,
	"target_timerange": {
	"duration": 1566666, // 图片持续时间
	"start": 0   // 图片起始时间
	},
	"template_id": "",
	"template_scene": "default",
	"track_attribute": 0,
	"track_render_index": 0,
	"uniform_scale": {
	"on": true,
	"value": 1
	},
	"visible": true,
	"volume": 1
	}

以上就是添加图片draft_content.json文件会变化的数据

我们再来观察draft_meta_info.json里的变化情况
在这里插入图片描述
draft_fold_path剪映草稿的目录加上草稿的名字
draft_id 唯一id
draft_materials轨道,存放文件的信息,这个咱们待会分析
draft_name这个草稿的名字
draft_root_path剪映草稿的目录
draft_timeline_materials_size_ 草稿的大小 (不重要)
tm_draft_create 时间戳(不重要)
tm_draft_modified 时间戳(不重要)
tm_duration 动画持续时间
而添加图片会放在draft_materials的数组里的第一条轨道的value里,分析一下
在这里插入图片描述

{
	"create_time": 1699987869,
	"duration": 5000000,  // 动画持续时间5秒
	"extra_info": "1.png",   // 图片的名字
	"file_Path": "C:/Users/lsl/Desktop/tttest/1.png", //图片完整路劲
	"height": 1080,  // 图片高度
	"id": "c7b73489-d34d-4c4a-a0e2-f1bd3f038f39",  // 唯一ID
	"import_time": 1699987869,
	"import_time_ms": 1699987869000,
	"item_source": 1,
	"md5": "",
	"metetype": "photo",  //类型
	"roughcut_time_range": {
	"duration": -1,
	"start": -1
	},
	"sub_time_range": {
	"duration": -1,
	"start": -1
	},
	"type": 0,
	"width": 1080  // 图片宽度
},

4 张图片会添加4个item数据,
在这里插入图片描述
以上就是添加图片后draft_meta_info.json里的变化。现在咱们再来分析一下添加音频会添加哪些数据

添加音频
draft_content.json的变化
materials下的audios
materials下的beats
materials下的sound_channel_mappings
materials下的speeds
materials下的vocal_separations
注意:上述我们说到添加图片会在tracks里只会添加一个,而里面的segments会添加4张图片的数据,而音频也同理,也会在tracks里添加一条数据,segments里添加4段音频的数据,注意type类型则再是video了,而是audio
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在我们来分析有哪些数据添加了并且需要动态变化的

audios里的数据

{
	"app_id": 0,
	"category_id": "",
	"category_name": "local",
	"check_flag": 1,
	"duration": 1566666,  // 音频时长
	"effect_id": "",
	"formula_id": "",
	"id": "F8C76CD8-1938-4072-B330-F00BE97D1AAF",  // 对应tracks里segments下的material_id
	"intensifies_path": "",
	"local_material_id": "699D4C4F-C5A1-44EC-9550-30F5BE027993", // 唯一
	"music_id": "5F138CCF-A11F-41C1-98CF-61844FCBD12B", // 唯一
	"name": "1.mp3", //音频名字
	"path": "C:/Users/lsl/Desktop/音频文件/1.mp3", // 音频完整路劲
	"query": "",
	"request_id": "",
	"resource_id": "",
	"search_id": "",
	"source_platform": 0,
	"team_id": "",
	"text_id": "",
	"tone_category_id": "",
	"tone_category_name": "",
	"tone_effect_id": "",
	"tone_effect_name": "",
	"tone_speaker": "",
	"tone_type": "",
	"type": "extract_music",  // 音频类型,默认写死就行
	"video_id": "",
	"wave_points": []
}

beats 的 数据

{
	"ai_beats": {
	"beat_speed_infos": [],
	"beats_path": "",
	"beats_url": "",
	"melody_path": "",
	"melody_percents": [
	0
	],
	"melody_url": ""
	},
	"enable_ai_beats": false,
	"gear": 404,
	"gear_count": 0,
	"id": "2745FAB5-636F-4B00-9656-D03A9D7CEE7E", // 对应tracks里segments下的 extra_material_refs里的第二个id
	"mode": 404,
	"type": "beats",
	"user_beats": [],
	"user_delete_ai_beats": null
}

sound_channel_mappings 的数据

{
   "audio_channel_mapping": 0,
   "id": "6FF237FE-075A-4CCD-934B-631A50B6FBC7", // 对应tracks里segments下的 extra_material_refs里的第三个id
   "is_config_open": false,
   "type": "none"
}

speeds的数据

{
	"curve_speed": null,
	"id": "C6127B0F-128A-4738-96B5-F0C377BA4361",// 对应tracks里segments下的 extra_material_refs里的第一个id
	"mode": 0,
	"speed": 1,
	"type": "speed"
}

vocal_separations的数据

{
	"choice": 0,
	"id": "6F67B5E1-F179-41E8-96E2-F60F38BBB095", // 对应tracks里segments下的 extra_material_refs里的第四个id
	"production_path": "",
	"time_range": null,
	"type": "vocal_separation"
}

segments 的 数据

{
	"cartoon": false,
	"clip": {
	"alpha": 1,
	"flip": {
	"horizontal": false,
	"vertical": false
	},
	"rotation": 0,
	"scale": {
	"x": 1,
	"y": 1
	},
	"transform": {
	"x": 0,
	"y": 0
	}
	},
	"common_keyframes": [],
	"enable_adjust": true,
	"enable_color_curves": true,
	"enable_color_match_adjust": false,
	"enable_color_wheels": true,
	"enable_lut": true,
	"enable_smart_color_adjust": false,
	"extra_material_refs": [
	"DC6EC53C-3497-46CE-AF3A-61B002016226",  // 对应speeds的id
	"4B6E427A-A0CE-4CB5-8FDD-625D3C46FFD1",	 // 对应beats的id
	"03559466-D479-45D4-ACE8-5C93C295C32C",	 // 对应sound_channel_mappings的id
	"BB3B2A8D-31ED-4AF3-BB2F-389F52FE714D"	 // 对应vocal_separations的id
	],
	"group_id": "",
	"hdr_settings": {
	"intensity": 1,
	"mode": 1,
	"nits": 1000
	},
	"id": "BCC33EDD-DB17-4E5F-9949-B1AEC1D94BF0",  // 唯一
	"intensifies_audio": false,
	"is_placeholder": false,
	"is_tone_modify": false,
	"keyframe_refs": [],
	"last_nonzero_volume": 1,
	"material_id": "13F7F3F1-663C-4F28-8616-489EB3799964", // audios的id
	"render_index": 0,
	"responsive_layout": {
	"enable": false,
	"horizontal_pos_layout": 0,
	"size_layout": 0,
	"target_follow": "",
	"vertical_pos_layout": 0
	},
	"reverse": false,
	"source_timerange": {
	"duration": 1566666,  // 音频持续时间
	"start": 0
	},
	"speed": 1,
	"target_timerange": {
	"duration": 1566666,
	"start": 0
	},
	"template_id": "",
	"template_scene": "default",
	"track_attribute": 0,
	"track_render_index": 0,
	"uniform_scale": {
	"on": true,
	"value": 1
	},
	"visible": true,
	"volume": 1
}

tracks的数据

{
	"attribute": 0,
	"flag": 0,
	"id": "62277D1A-A0A6-48A1-89B9-14A6580A5DE9",  // 唯一
	"is_default_name": true,
	"name": "",
	"segments": [],
	"type": "audio"  // 类型
}

以上就是添加音频后draft_content.json的数据变化了,现在我们来看draft_meta_info.json的数据变化

在这里插入图片描述
其他数据我们上面在分析添加图片的时候讲过在这里就不讲了,只需要注意draft_materials添加的数据

在这里插入图片描述

{
	"create_time": 1699987869, // 创建时间  int(time.time())
	"duration": 1563333,   // 音频时长
	"extra_info": "3.mp3",  // 音频名字
	"file_Path": "C:/Users/lsl/Desktop/音频文件/3.mp3",  // 音频完整路劲
	"height": 0, // 如果是音频的话,直接写死0
	"id": "30df8daf-974a-4a06-b4fd-5f6404892267",
	"import_time": 1699987869,			//  int(time.time())
	"import_time_ms": 1699987869000,   // 导入时间毫秒级
	"item_source": 1,
	"md5": "",
	"metetype": "music",   // 音频类型,写死music
	"roughcut_time_range": {
	"duration": 1563333, // 音频时长
	"start": -1
	},
	"sub_time_range": {
	"duration": -1,
	"start": -1
	},
	"type": 0,
	"width": 0 // 如果是音频的话,直接写死0
}

以上就是添加音频后draft_meta_info.json的变化了,现在分析了数据就可以用代码来创建草稿

思路

先读取,模板。也就是我们一开始创建的
在这里插入图片描述
在初始化的时候就读取

    def init_data(self):
        """
        初始化数据
        """
        self.template_meta_info_path, self.template_meta_content_path = template_path()  # 返回两个模版的完整路劲
        self.draft_content_template = read_json(self.template_meta_content_path)  # 模版1
        self.draft_meta_template = read_json(self.template_meta_info_path)  # 模版2

        self.draft_content_template['id'] = generate_id()  # 给模版ID设置唯一id
        tracks_video_data = tracks()  # 创建tracks用于存放图片信息
        tracks_video_data['type'] = 'video'  # 类型
        self.draft_content_template['tracks'].append(tracks_video_data)  # 添加到模板里

        tracks_audio_data = tracks()  # 创建tracks用于存放音频信息
        tracks_audio_data['type'] = 'audio'  # 类型
        self.draft_content_template['tracks'].append(tracks_audio_data)  # 添加到模板里

        self.draft_meta_template['draft_id'] = generate_id()  # 给模版ID设置唯一id
        self.draft_meta_template[
            'draft_root_path'] = self.base_path  # 剪映的草稿路劲 如:D:\\\\software\\\\剪映\\\\JianyingPro Drafts
        self.draft_meta_template['tm_draft_create'] = int(time.time() * 1000)  # draft_meta_info.json创建时间,时间戳
        self.draft_meta_template['tm_draft_modified'] = generate_16_digit_timestamp()  # 13或16位毫秒级时间戳
        self.draft_meta_template['draft_removable_storage_device'] = get_drive_from_path(self.base_path)  # 磁盘的驱动器 如"D:"
        self.draft_meta_template['draft_fold_path'] = self.folder_path.replace('\\',
                                                                               '/')  # 剪映安装路劲加上草稿名字 如: D:/software/剪映/JianyingPro Drafts/六合八荒唯我独尊
        self.draft_meta_template['draft_name'] = self.novel_name  # 草稿名字 如:"D:/software/剪映/JianyingPro Drafts/六合八荒唯我独尊"

读取音频文件夹的音频信息。读取音频文件夹里的音频文件信息和图片文件夹里的图片文件信息,用来循环添加数据。之前分析过JSON,有哪些数据变化我也注释出来了,这个需要你们自己往模版里添加

添加完了数据,记得计算一下音频的总时长,将draft_content.json的duration就等于所有音频时间想加,

最后将创建完整的两个模版json数据写入到剪映草稿目录下就行了。

    def write_data(self):
        """
        创建文件,并写入数据
        """
        # 创建文件夹
        os.makedirs(self.folder_path, exist_ok=True)
        # 创建 draft_meta_info.json
        with open(self.meta_info_path, 'w', encoding='utf-8') as meta_info_file:
            json.dump(self.draft_meta_template, meta_info_file, indent=4, ensure_ascii=False)

        with open(self.content_path, 'w', encoding='utf-8') as content_file:
            json.dump(self.draft_content_template, content_file, indent=4, ensure_ascii=False)

准备好各个items的模版,有一些唯一id用uuid生成就行了,这些是我写的代码各位可以参考使用。
到这里就结束了。

# utils
import base64
import time
import uuid
import json
from PIL import Image
from moviepy.editor import *


def generate_id():
    """
    生成uuid(大写)
    """
    return str(uuid.uuid4()).upper() 

def read_json(path):
    """
    加载模板JSON
    """
    try:
        with open(path, 'r', encoding="utf-8") as template_meta_info_file:
            info_data = json.load(template_meta_info_file)
            return info_data
    except Exception as e:
        print(f"Error: {e}")
        return None

def process_image(file_path):
    """
    获取图片信息
    """
    try:
        # 提取文件名
        file_name = os.path.basename(file_path)

        # 打开图片文件
        with Image.open(file_path) as img:
            # 获取图片的宽度和高度
            width, height = img.size
            # 宽度、高度、完整路径和文件名
            image_info = {
                'file_path': file_path,
                'file_name': file_name,
                'width': width,
                'height': height
            }
            return image_info
    except Exception as e:
        # 处理可能的异常,比如无法打开文件或不是有效的图片文件
        print(f"Error processing file {file_path}: {e}")
        return None

def process_images_in_folder(folder_path):
    """
    返回图片信息以及完整路劲
    """
    image_info_array = []

    # 遍历文件夹中的文件
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            # 检查文件扩展名,确保它是图片文件
            if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tif')):
                # 获取图片文件的完整路径
                image_path = os.path.join(root, file).replace('\\', '/')

                # 处理图片文件
                image_info = process_image(image_path)

                # 将image_info添加到数组中
                if image_info:
                    image_info_array.append(image_info)

    return image_info_array


def template_path():
    """
    :return: 模板草稿的完整路劲
    """
    # 获取当前文件所在目录的路径
    current_folder_path = os.path.dirname(os.path.abspath(__file__))
    # 构建 template 文件夹的路径
    template_folder_path = os.path.join(current_folder_path, 'templatejson')
    # 构建 draft_meta_info.json 文件的完整路径
    template_meta_info_path = os.path.join(template_folder_path, 'draft_meta_data.json')
    template_meta_content_path = os.path.join(template_folder_path, 'draft_content_data.json')

    return template_meta_info_path, template_meta_content_path

def process_audio(file_path):
    """
    获取音频信息
    """
    try:
        # 提取文件名
        file_name = os.path.basename(file_path)

        # 读取音频文件
        clip = AudioFileClip(file_path)

        # 获取音频时长
        audio_duration = int(clip.duration * 1_000_000) + 3333 # 这里是转成剪映的

        audio_info = {
            'file_path': file_path,
            'file_name': file_name,
            'duration': audio_duration,
            'filetype': 'audio'
        }

        return audio_info
    except Exception as e:
        # 处理可能的异常,比如无法打开文件或不是有效的音频文件
        print(f"处理文件 {file_path} 时出错:{e}")
        return None


def process_audios_in_folder(folder_path):
    """
    返回音频信息以及完整路劲
    """
    audio_info_array = []

    # 遍历文件夹中的文件
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            # 检查文件扩展名,确保它是音频文件
            if file.lower().endswith(('.wav', '.mp3', '.ogg', '.aac', '.m4a')):
                # 获取音频文件的完整路径
                audio_path = os.path.join(root, file).replace('\\', '/')

                # 处理音频文件
                audio_info = process_audio(audio_path)

                # 将audio_info添加到数组中
                if audio_info:
                    audio_info_array.append(audio_info)

    return audio_info_array

需要用到的模版代码,我已经将唯一的uuid在导出的时候就生成了

from apps.utils import *


def tracks():
    return {
        "attribute": 0,
        "flag": 0,
        "id": generate_id(),
        "is_default_name": True,
        "name": "",
        "segments": [],
        "type": ""
    }


def segment_video():
    return {
        "cartoon": False,
        "clip": {
            "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
            }
        },
        "common_keyframes": [],
        "enable_adjust": True,
        "enable_color_curves": True,
        "enable_color_match_adjust": False,
        "enable_color_wheels": True,
        "enable_lut": True,
        "enable_smart_color_adjust": False,
        "extra_material_refs": [],
        "group_id": "",
        "hdr_settings": {
            "intensity": 1.0,
            "mode": 1,
            "nits": 1000
        },
        "id": generate_id(),
        "intensifies_audio": False,
        "is_placeholder": False,
        "is_tone_modify": False,
        "keyframe_refs": [],
        "last_nonzero_volume": 1.0,
        "material_id": "",
        "render_index": 0,
        "responsive_layout": {
            "enable": False,
            "horizontal_pos_layout": 0,
            "size_layout": 0,
            "target_follow": "",
            "vertical_pos_layout": 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
    }


def segment_audio():
    return {
        "cartoon": False,
        "clip": None,
        "common_keyframes": [],
        "enable_adjust": False,
        "enable_color_curves": True,
        "enable_color_match_adjust": False,
        "enable_color_wheels": True,
        "enable_lut": False,
        "enable_smart_color_adjust": False,
        "extra_material_refs": [],
        "group_id": "",
        "hdr_settings": None,
        "id": generate_id(),
        "intensifies_audio": False,
        "is_placeholder": False,
        "is_tone_modify": False,
        "keyframe_refs": [],
        "last_nonzero_volume": 1.0,
        "material_id": "",
        "render_index": 0,
        "responsive_layout": {
            "enable": False,
            "horizontal_pos_layout": 0,
            "size_layout": 0,
            "target_follow": "",
            "vertical_pos_layout": 0
        },
        "reverse": False,
        "source_timerange": {
            "duration": 0,
            "start": 0
        },
        "speed": 1.0,
        "target_timerange": {
            "duration": 0,
            "start": 0
        },
        "template_id": "",
        "template_scene": "default",
        "track_attribute": 0,
        "track_render_index": 0,
        "uniform_scale": None,
        "visible": True,
        "volume": 1.0
    }


def vocal():
    return {
        "choice": 0,
        "id": "",
        "production_path": "",
        "time_range": None,
        "type": "vocal_separation"
    }


def videos_items():
    return {
        "aigc_type": "none",
        "audio_fade": None,
        "cartoon_path": "",
        "category_id": "",
        "category_name": "local",
        "check_flag": 63487,
        "crop": {
            "lower_left_x": 0.0,
            "lower_left_y": 1.0,
            "lower_right_x": 1.0,
            "lower_right_y": 1.0,
            "upper_left_x": 0.0,
            "upper_left_y": 0.0,
            "upper_right_x": 1.0,
            "upper_right_y": 0.0
        },
        "crop_ratio": "free",
        "crop_scale": 1.0,
        "duration": 10800000000,
        "extra_type_option": 0,
        "formula_id": "",
        "freeze": None,
        "gameplay": None,
        "has_audio": False,
        "height": 0,
        "id": "",
        "intensifies_audio_path": "",
        "intensifies_path": "",
        "is_ai_generate_content": False,
        "is_unified_beauty_mode": False,
        "local_id": "",
        "local_material_id": "",
        "material_id": "",
        "material_name": "",
        "material_url": "",
        "matting": {
            "flag": 0,
            "has_use_quick_brush": False,
            "has_use_quick_eraser": False,
            "interactiveTime": [],
            "path": "",
            "strokes": []
        },
        "media_path": "",
        "object_locked": None,
        "origin_material_id": "",
        "path": "",
        "picture_from": "none",
        "picture_set_category_id": "",
        "picture_set_category_name": "",
        "request_id": "",
        "reverse_intensifies_path": "",
        "reverse_path": "",
        "smart_motion": None,
        "source": 0,
        "source_platform": 0,
        "stable": {
            "matrix_path": "",
            "stable_level": 0,
            "time_range": {
                "duration": 0,
                "start": 0
            }
        },
        "team_id": "",
        "type": "photo",
        "video_algorithm": {
            "algorithms": [],
            "deflicker": None,
            "motion_blur_config": None,
            "noise_reduction": None,
            "path": "",
            "quality_enhance": None,
            "time_range": None
        },
        "width": 0
    }


def speeds_items():
    return {
        "curve_speed": None,
        "id": "",
        "mode": 0,
        "speed": 1.0,
        "type": "speed"
    }


def sound_items():
    return {
        "audio_channel_mapping": 0,
        "id": "",
        "is_config_open": False,
        "type": ""
    }


def canvases_items():
    return {
        "album_image": "",
        "blur": 0.0,
        "color": "",
        "id": "",
        "image": "",
        "image_id": "",
        "image_name": "",
        "source_platform": 0,
        "team_id": "",
        "type": "canvas_color"
    }


def beats_items():
    return {
        "ai_beats": {
            "beat_speed_infos": [],
            "beats_path": "",
            "beats_url": "",
            "melody_path": "",
            "melody_percents": [
                0.0
            ],
            "melody_url": ""
        },
        "enable_ai_beats": False,
        "gear": 404,
        "gear_count": 0,
        "id": "",
        "mode": 404,
        "type": "beats",
        "user_beats": [],
        "user_delete_ai_beats": None
    }


def audios():
    return {
        "app_id": 0,
        "category_id": "",
        "category_name": "local",
        "check_flag": 1,
        "duration": 0,
        "effect_id": "",
        "formula_id": "",
        "id": "",
        "intensifies_path": "",
        "local_material_id": generate_id(),
        "music_id": generate_id(),
        "name": "",
        "path": "",
        "query": "",
        "request_id": "",
        "resource_id": "",
        "search_id": "",
        "source_platform": 0,
        "team_id": "",
        "text_id": "",
        "tone_category_id": "",
        "tone_category_name": "",
        "tone_effect_id": "",
        "tone_effect_name": "",
        "tone_speaker": "",
        "tone_type": "",
        "type": "extract_music",
        "video_id": "",
        "wave_points": []
    }


def draft_materials_items():
    return {
        "create_time": int(time.time()),
        "duration": 0,
        "extra_info": "",
        "file_Path": "",
        "height": 0,
        "id": generate_id2(),
        "import_time": int(time.time()),
        "import_time_ms": int(time.time()) * 10 ** 3,
        "item_source": 1,
        "md5": "",
        "metetype": "0",
        "roughcut_time_range": {
            "duration": -1,
            "start": -1
        },
        "sub_time_range": {
            "duration": -1,
            "start": -1
        },
        "type": 0,
        "width": 0
    }


def material_animations_items():
    return {
        "animations": [],
        "id": "",
        "type": "sticker_animation"
    }

成果展示一下!
在这里插入图片描述

  • 19
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
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):
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值