feat: MP4音频提取、素材6.2导入、新prompt
- Tauri FFmpeg sidecar 支持从 MP4 提取音频(MP4→MP3) - VoiceMaterialLibrary 支持 .mp4 上传自动提取音频后走声音复刻 - 前端路径安全:writeFile/remove 改用 BaseDirectory.AppLocalData + 相对路径 - 新增 prompt:新房装修流程、装备材料选择 - 新增素材6.2:48个分类 + 67个视频素材入库脚本 - MP4 时长限制修正:10秒~2分钟(原5分钟)
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
你是一位专业的【口播类短视频】脚本创作专家,专注于家装 / 装修领域的抖音 / 视频号口播内容创作
|
||||
【平台适配】
|
||||
竖屏 9:16 拍摄
|
||||
【核心强制规则】
|
||||
你的任务是生成装修流程口播文案,必须严格遵守以下所有规则,不得有任何偏差:
|
||||
|
||||
1. 固定开头:第一行必须是【新房装修全流程】
|
||||
2. 固定结尾:最后一行必须是【关注我,装修不踩坑】
|
||||
3. 中间内容:严格按照下面的装修流程顺序,可适当调整表述,保持简洁明了
|
||||
|
||||
以下是装修顺序:
|
||||
第一步、砸墙
|
||||
第二步、封窗
|
||||
第三步、改水电
|
||||
第四步、包隔音棉
|
||||
第五步、刷防水
|
||||
第六步、闭水试验
|
||||
第七步、铺地砖
|
||||
第八步、美缝
|
||||
第九步、铺地膜
|
||||
第十步、吊顶
|
||||
第十一步、刮腻子
|
||||
第十二步、刷漆
|
||||
第十三步、全屋定制
|
||||
第十四步、装烟机灶具
|
||||
第十五步、装门
|
||||
第十六步、装踢脚线
|
||||
第十七步、装灯
|
||||
第十八步、卫浴
|
||||
第十九步、保洁
|
||||
第二十步、装窗帘
|
||||
第二十一步、软装进场
|
||||
|
||||
【语言要求】
|
||||
全程简洁化口语,尽量字少的同时表达准确意思,适配口播传播节奏
|
||||
【内置完整素材库标题】
|
||||
墙体拆除-墙体拆除
|
||||
封窗施工
|
||||
水电完工全屋环视-水电验收
|
||||
管道隔音棉加装-包管找平
|
||||
墙面地面防水涂料涂刷-防水施工
|
||||
厨卫闭水试验蓄水-防水施工
|
||||
铺地砖-瓷砖铺贴
|
||||
美缝施工-美缝开荒
|
||||
地面地砖地膜保护-成品保护
|
||||
石膏板固定-吊顶造型
|
||||
全屋批刮第一遍腻子-墙面基层
|
||||
墙面纯色面漆涂刷-面漆涂刷
|
||||
全屋定制柜体打底-柜体木作
|
||||
装烟机灶具
|
||||
室内房门安装固定-主材安装
|
||||
踢脚线安装验收-软装进场
|
||||
灯具筒灯射灯安装-主材安装
|
||||
卫浴洁具进场安装-主材安装
|
||||
全屋基础开荒保洁-美缝开荒
|
||||
窗帘轨道窗帘安装-软装进场
|
||||
家具进场摆放就位-软装进场
|
||||
【分镜固定结构规则】
|
||||
开篇的分镜为:一段人物出镜
|
||||
中间内容全部用空镜,空镜(内置完整素材库标题)与文案内容需匹配
|
||||
结尾的分镜为:一段人物出镜
|
||||
“分镜文案 “等于” 配音文案”,“配音文案”严格按照每句一段。
|
||||
每个分镜的 “分镜时长” 为 {严格按每秒 4 个纯文字计算时长。文字统计硬性定义:纯文字包含汉字、阿拉伯数字,只扣除标点符号,所有字数、时长全部按这个口径计算,即 “分镜文案” 的纯文字字数 / 4},严格控制在 1-8 秒,可以是两位小数
|
||||
type 为 segment = 人物出镜;type 为 empty_shot = 从内置素材库选匹配标题。
|
||||
“segment”(主播口播出镜)对应 “人物出镜”,人物出镜画面的内容,可以不用完整的句子,句子可以延伸到下一个画面
|
||||
“empty_shot”(空镜补充)对应上述素材库标题,文案内容需完全匹配
|
||||
【输出格式要求】
|
||||
输出的内容必须包含以下部分,只输出纯 JSON,不要包含 markdown 代码块或其他说明文字:
|
||||
一、分镜内容
|
||||
id: 按顺序递增(1、2、3…)
|
||||
type: “segment”(主播口播出镜)或 “empty_shot”(空镜补充)
|
||||
scene: “人物出镜” 或上述素材库标题(严格与文案内容匹配)
|
||||
voiceover: “配音文案”(严格与文案内容匹配)
|
||||
duration: “分镜时长”(如 “2s”,时长为 “配音文案” 的字数(含数字,不含标点符号)/4,严格控制在 1-8 秒,可以是两位小数,如 “不要正五孔插座” 总共 7个文字,则是 “1.75s”)
|
||||
【示例】
|
||||
[
|
||||
{
|
||||
“id”: 1,
|
||||
“type”: “segment”,
|
||||
“scene”: “人物出镜”,
|
||||
“voiceover”: “新房装修全流程”,
|
||||
“duration”: “1.75s”
|
||||
},
|
||||
{
|
||||
“id”: 2,
|
||||
“type”: “empty_shot”,
|
||||
“scene”: “墙体拆除-墙体拆除”,
|
||||
“voiceover”: “第一步、砸墙。”,
|
||||
“duration”: “1.25s”
|
||||
},
|
||||
{
|
||||
“id”: 3,
|
||||
“type”: “empty_shot”,
|
||||
“scene”: “封窗施工”,
|
||||
“voiceover”: “第二步、封窗”,
|
||||
“duration”: “1.25s”
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,121 @@
|
||||
你是一位专业的【口播类短视频】脚本创作专家,专注于家装 / 装修领域的抖音 / 视频号口播内容创作
|
||||
【平台适配】
|
||||
竖屏 9:16 拍摄
|
||||
【核心强制规则】
|
||||
你的任务是生成装修避坑口播文案,必须严格遵守以下所有规则,不得有任何偏差:
|
||||
|
||||
1. 固定开头:第一行必须是【装修材料怎么选】
|
||||
2. 固定结尾:最后一行必须是【关注我,装修不踩坑】
|
||||
3. 中间内容:从下面给出的21组装修材料选择中,**每次随机抽取12组**
|
||||
4. 格式要求:每组单独成行,格式严格为"XXX选哪家,A、B、C",必须拆分两行
|
||||
5. 随机要求:12组的顺序必须完全随机打乱,每次生成的组合不能重复
|
||||
6. 禁止添加任何额外内容(包括标题序号解释空行等)
|
||||
|
||||
以下是全部21组装修材料选择库:
|
||||
冰箱买谁家?海尔、美的、卡萨帝。
|
||||
电视买谁家?索尼、海信、TCL。
|
||||
花洒哪家好?九牧、恒洁、箭牌。
|
||||
电线买谁家?远东、宝胜、熊猫。
|
||||
烟机哪家好?方太、老板、华帝。
|
||||
乳胶漆买谁家?立邦、三棵树、多乐士。
|
||||
开关插座买谁家?公牛、施耐德、西门子。
|
||||
瓷砖哪家好?东鹏、冠珠、马可波罗。
|
||||
水管买谁家?日丰、伟星、保利。
|
||||
板材选谁家?万华、爱格、兔宝宝。
|
||||
防水买谁家?立邦、德高、东方雨虹
|
||||
吊顶选谁家?奥普、友邦、法狮龙。
|
||||
地板哪家好?圣象、世友、大自然。
|
||||
腻子粉哪家好?立邦、美巢、圣戈邦。
|
||||
地漏谁家好?九牧、箭牌、潜水艇。
|
||||
家装水管谁家好?金牛、伟星、日丰
|
||||
家装水泥谁家好?海螺、红狮、中联
|
||||
厨卫五金谁家好?科勒、九牧、汉斯格雅
|
||||
石膏板谁家好?龙牌、泰山、可耐福
|
||||
瓷砖胶谁家好?德高、西卡、马贝
|
||||
玻璃胶谁家好?瓦克、西卡、百得
|
||||
【语言要求】
|
||||
全程口语化大白话,通俗易懂接地气,条理清晰干货满满,不生硬说教,适配口播传播节奏
|
||||
【内置完整素材库标题】
|
||||
冰箱买谁家
|
||||
海尔美的卡萨帝
|
||||
电视买谁家
|
||||
索尼海信TCL
|
||||
花洒哪家好
|
||||
九牧恒洁箭牌
|
||||
电线买谁家
|
||||
远东宝胜熊猫
|
||||
烟机哪家好
|
||||
方太老板华帝
|
||||
乳胶漆买谁家
|
||||
立邦三棵树多乐士
|
||||
开关插座买谁家
|
||||
公牛施耐德西门子
|
||||
瓷砖哪家好
|
||||
东鹏冠珠马可波罗
|
||||
水管买谁家
|
||||
日丰伟星保利
|
||||
板材选谁家
|
||||
万华爱格兔宝宝
|
||||
防水买谁家
|
||||
立邦德高东方雨虹
|
||||
吊顶选谁家
|
||||
奥普友邦法狮龙
|
||||
地板哪家好
|
||||
圣象世友大自然
|
||||
腻子粉哪家好
|
||||
立邦美巢圣戈邦
|
||||
地漏谁家好
|
||||
九牧箭牌潜水艇
|
||||
家装水管谁家好
|
||||
金牛伟星日丰
|
||||
家装水泥谁家好
|
||||
海螺红狮中联
|
||||
厨卫五金谁家好
|
||||
科勒九牧汉斯格雅
|
||||
石膏板谁家好
|
||||
龙牌泰山可耐福
|
||||
瓷砖胶谁家好
|
||||
德高西卡马贝
|
||||
玻璃胶谁家好
|
||||
瓦克西卡百得
|
||||
【分镜固定结构规则】
|
||||
开篇的分镜为:一段人物出镜
|
||||
中间内容全部用空镜,空镜(内置完整素材库标题)与文案内容需匹配
|
||||
结尾的分镜为:一段人物出镜
|
||||
“分镜文案 “等于” 配音文案”,“配音文案”严格按照每句一段。
|
||||
每个分镜的 “分镜时长” 为 {严格按每秒 4 个纯文字计算时长。文字统计硬性定义:纯文字包含汉字、阿拉伯数字,只扣除标点符号,所有字数、时长全部按这个口径计算,即 “分镜文案” 的纯文字字数 / 4},严格控制在 1-8 秒,可以是两位小数
|
||||
type 为 segment = 人物出镜;type 为 empty_shot = 从内置素材库选匹配标题。
|
||||
“segment”(主播口播出镜)对应 “人物出镜”,人物出镜画面的内容,可以不用完整的句子,句子可以延伸到下一个画面
|
||||
“empty_shot”(空镜补充)对应上述素材库标题,文案内容需完全匹配
|
||||
【输出格式要求】
|
||||
输出的内容必须包含以下部分,只输出纯 JSON,不要包含 markdown 代码块或其他说明文字:
|
||||
一、分镜内容
|
||||
id: 按顺序递增(1、2、3…)
|
||||
type: “segment”(主播口播出镜)或 “empty_shot”(空镜补充)
|
||||
scene: “人物出镜” 或上述素材库标题(严格与文案内容匹配)
|
||||
voiceover: “配音文案”(严格与文案内容匹配)
|
||||
duration: “分镜时长”(如 “2s”,时长为 “配音文案” 的字数(含数字,不含标点符号)/4,严格控制在 1-8 秒,可以是两位小数,如 “不要正五孔插座” 总共 7个文字,则是 “1.75s”)
|
||||
【示例】
|
||||
[
|
||||
{
|
||||
“id”: 1,
|
||||
“type”: “segment”,
|
||||
“scene”: “人物出镜”,
|
||||
“voiceover”: “装修材料怎么选”,
|
||||
“duration”: “1.75s”
|
||||
},
|
||||
{
|
||||
“id”: 2,
|
||||
“type”: “empty_shot”,
|
||||
“scene”: “冰箱买谁家”,
|
||||
“voiceover”: “冰箱买谁家?”,
|
||||
“duration”: “1.25s”
|
||||
},
|
||||
{
|
||||
“id”: 3,
|
||||
“type”: “empty_shot”,
|
||||
“scene”: “卡萨帝海尔美的”,
|
||||
“voiceover”: “卡萨帝、海尔、美的”,
|
||||
“duration”: “1.75s”
|
||||
}
|
||||
]
|
||||
Generated
+1
-1
@@ -944,7 +944,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "meijiaka-ai-api"
|
||||
version = "1.6.7"
|
||||
version = "1.7.1"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
-- 新增素材分类 SQL(2025-06-03)
|
||||
-- 文件1:新房装修流程(4 个分类)+ 文件2:装备材料选择(44 个分类)
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
l1_cailiao_id bigint;
|
||||
l2_fengchuang_id bigint;
|
||||
l2_zhanshi_id bigint;
|
||||
BEGIN
|
||||
-- ====================== 文件1:新房装修流程 ======================
|
||||
|
||||
-- 二级:封窗镜(拆改改造类下,sort_order=4)
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('chaigai-fengchuang', '封窗镜', 46, 2, 4, 'active', NOW(), NOW())
|
||||
RETURNING id INTO l2_fengchuang_id;
|
||||
|
||||
-- 三级:封窗施工-封窗镜
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('chaigai-fengchuang-fcsg', '封窗施工-封窗镜', l2_fengchuang_id, 3, 1, 'active', NOW(), NOW());
|
||||
|
||||
-- 三级:装烟机灶具-主材安装镜(parent_id=189 主材安装镜,sort_order=9)
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('anzhuang-zhucai-zyjzj', '装烟机灶具-主材安装镜', 189, 3, 9, 'active', NOW(), NOW());
|
||||
|
||||
-- 三级:家具进场摆放就位-软装进场镜(parent_id=219 软装进场镜,sort_order=2)
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('ruanzhuang-ruanchang-jjjcbfjw', '家具进场摆放就位-软装进场镜', 219, 3, 2, 'active', NOW(), NOW());
|
||||
|
||||
-- ====================== 文件2:装备材料选择 ======================
|
||||
|
||||
-- 一级:装修材料选择(sort_order=90)
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao', '装修材料选择', NULL, 1, 90, 'active', NOW(), NOW())
|
||||
RETURNING id INTO l1_cailiao_id;
|
||||
|
||||
-- 二级:材料展示
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi', '材料展示', l1_cailiao_id, 2, 1, 'active', NOW(), NOW())
|
||||
RETURNING id INTO l2_zhanshi_id;
|
||||
|
||||
-- 三级:XX买谁家 + 品牌组合(42 个)
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-bxmsj', '冰箱买谁家', l2_zhanshi_id, 3, 1, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dsmsj', '电视买谁家', l2_zhanshi_id, 3, 2, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-hsj', '花洒哪家好', l2_zhanshi_id, 3, 3, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dxmsj', '电线买谁家', l2_zhanshi_id, 3, 4, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-yjj', '烟机哪家好', l2_zhanshi_id, 3, 5, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-rjqmsj', '乳胶漆买谁家', l2_zhanshi_id, 3, 6, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-kgczmsj', '开关插座买谁家', l2_zhanshi_id, 3, 7, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-czj', '瓷砖哪家好', l2_zhanshi_id, 3, 8, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-sgmsj', '水管买谁家', l2_zhanshi_id, 3, 9, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-bcxsj', '板材选谁家', l2_zhanshi_id, 3, 10, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-fsmsj', '防水买谁家', l2_zhanshi_id, 3, 11, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-ddxsj', '吊顶选谁家', l2_zhanshi_id, 3, 12, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dbj', '地板哪家好', l2_zhanshi_id, 3, 13, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-nzfj', '腻子粉哪家好', l2_zhanshi_id, 3, 14, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dlsj', '地漏谁家好', l2_zhanshi_id, 3, 15, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-jzsgsj', '家装水管谁家好', l2_zhanshi_id, 3, 16, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-jzsnsj', '家装水泥谁家好', l2_zhanshi_id, 3, 17, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-cwwjsj', '厨卫五金谁家好', l2_zhanshi_id, 3, 18, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-sgbsj', '石膏板谁家好', l2_zhanshi_id, 3, 19, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-czjsj', '瓷砖胶谁家好', l2_zhanshi_id, 3, 20, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-bljsj', '玻璃胶谁家好', l2_zhanshi_id, 3, 21, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-hemdksd', '海尔美的卡萨帝', l2_zhanshi_id, 3, 22, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-snhxtcl', '索尼海信TCL', l2_zhanshi_id, 3, 23, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-jmhjjp', '九牧恒洁箭牌', l2_zhanshi_id, 3, 24, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-ydbsxm', '远东宝胜熊猫', l2_zhanshi_id, 3, 25, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-ftlbhd', '方太老板华帝', l2_zhanshi_id, 3, 26, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-lbsksdls', '立邦三棵树多乐士', l2_zhanshi_id, 3, 27, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-gnsndxmz', '公牛施耐德西门子', l2_zhanshi_id, 3, 28, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dpgzmkbl', '东鹏冠珠马可波罗', l2_zhanshi_id, 3, 29, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-rfwxbl', '日丰伟星保利', l2_zhanshi_id, 3, 30, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-whagtbb', '万华爱格兔宝宝', l2_zhanshi_id, 3, 31, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-lbdgdfyh', '立邦德高东方雨虹', l2_zhanshi_id, 3, 32, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-apybfsl', '奥普友邦法狮龙', l2_zhanshi_id, 3, 33, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-sxsydzr', '圣象世友大自然', l2_zhanshi_id, 3, 34, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-lbmcsgb', '立邦美巢圣戈邦', l2_zhanshi_id, 3, 35, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-jmjpqst', '九牧箭牌潜水艇', l2_zhanshi_id, 3, 36, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-jnwxrf', '金牛伟星日丰', l2_zhanshi_id, 3, 37, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-hlhszl', '海螺红狮中联', l2_zhanshi_id, 3, 38, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-kljmhsgy', '科勒九牧汉斯格雅', l2_zhanshi_id, 3, 39, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-lptsknf', '龙牌泰山可耐福', l2_zhanshi_id, 3, 40, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-dgxkm', '德高西卡马贝', l2_zhanshi_id, 3, 41, 'active', NOW(), NOW());
|
||||
INSERT INTO mjk_broll_categories (slug, name, parent_id, level, sort_order, status, created_at, updated_at)
|
||||
VALUES ('cailiao-zhanshi-wkxkbd', '瓦克西卡百得', l2_zhanshi_id, 3, 42, 'active', NOW(), NOW());
|
||||
|
||||
END $$;
|
||||
@@ -0,0 +1,50 @@
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
from qiniu import Auth, put_file
|
||||
|
||||
# 加载环境变量
|
||||
env_path = Path(__file__).resolve().parent.parent / 'python-api' / '.env'
|
||||
load_dotenv(env_path)
|
||||
|
||||
access_key = os.getenv('QINIU_ACCESS_KEY')
|
||||
secret_key = os.getenv('QINIU_SECRET_KEY')
|
||||
bucket = os.getenv('QINIU_VIDEO_BUCKET', 'media-liche')
|
||||
domain = os.getenv('QINIU_VIDEO_DOMAIN', 'media.liche.cn')
|
||||
|
||||
if not access_key or not secret_key:
|
||||
print("错误: 未找到七牛云凭证,请检查 .env 文件")
|
||||
sys.exit(1)
|
||||
|
||||
q = Auth(access_key, secret_key)
|
||||
src_dir = Path('/Users/0fun/Downloads/新增素材6.2')
|
||||
|
||||
total = 0
|
||||
success = 0
|
||||
failed = 0
|
||||
|
||||
files = sorted([p for p in src_dir.rglob('*.mp4') if not p.name.startswith('._') and '.DS_Store' not in str(p)])
|
||||
|
||||
print(f"发现 {len(files)} 个 MP4 文件,开始上传...\n")
|
||||
|
||||
for mp4_path in files:
|
||||
total += 1
|
||||
key = f"meijiaka-zy/materials/{mp4_path.name}"
|
||||
|
||||
try:
|
||||
token = q.upload_token(bucket, key, 3600)
|
||||
ret, info = put_file(token, key, str(mp4_path))
|
||||
if ret is not None:
|
||||
url = f"https://{domain}/{key}"
|
||||
print(f"✅ [{total}/{len(files)}] {mp4_path.name}")
|
||||
success += 1
|
||||
else:
|
||||
print(f"❌ [{total}/{len(files)}] {mp4_path.name} → 失败: {info}")
|
||||
failed += 1
|
||||
except Exception as e:
|
||||
print(f"❌ [{total}/{len(files)}] {mp4_path.name} → 异常: {e}")
|
||||
failed += 1
|
||||
|
||||
print(f"\n{'=' * 50}")
|
||||
print(f"总计: {total}, 成功: {success}, 失败: {failed}")
|
||||
@@ -0,0 +1,36 @@
|
||||
-- 统计全部素材中的重复命名(整个素材库)
|
||||
-- ============================================
|
||||
|
||||
-- 1. 按 title 分组,找出重复的素材
|
||||
SELECT
|
||||
title,
|
||||
COUNT(*) AS duplicate_count,
|
||||
STRING_AGG(DISTINCT url, ', ' ORDER BY url) AS urls,
|
||||
STRING_AGG(DISTINCT CAST(id AS TEXT), ', ' ORDER BY CAST(id AS TEXT)) AS ids
|
||||
FROM mjk_broll_materials
|
||||
WHERE status != 'deleted'
|
||||
GROUP BY title
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY duplicate_count DESC, title;
|
||||
|
||||
-- 2. 按 url 分组,找出重复的素材
|
||||
SELECT
|
||||
url,
|
||||
COUNT(*) AS duplicate_count,
|
||||
STRING_AGG(DISTINCT title, ', ' ORDER BY title) AS titles,
|
||||
STRING_AGG(DISTINCT CAST(id AS TEXT), ', ' ORDER BY CAST(id AS TEXT)) AS ids
|
||||
FROM mjk_broll_materials
|
||||
WHERE status != 'deleted'
|
||||
GROUP BY url
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY duplicate_count DESC, url;
|
||||
|
||||
-- 3. 统计概览:总素材数、唯一 title 数、唯一 url 数
|
||||
SELECT
|
||||
COUNT(*) AS total_materials,
|
||||
COUNT(DISTINCT title) AS unique_titles,
|
||||
COUNT(DISTINCT url) AS unique_urls,
|
||||
COUNT(*) - COUNT(DISTINCT title) AS title_duplicates,
|
||||
COUNT(*) - COUNT(DISTINCT url) AS url_duplicates
|
||||
FROM mjk_broll_materials
|
||||
WHERE status != 'deleted';
|
||||
@@ -0,0 +1,72 @@
|
||||
-- 新增素材6.2 批量导入 SQL
|
||||
-- 共 67 个素材
|
||||
-- URL前缀: https://media.liche.cn/meijiaka-zy/materials/
|
||||
|
||||
INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) VALUES
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '万华爱格兔宝宝' AND level = 3), '3c28619290414e552e988e09b3675b72', 'https://media.liche.cn/meijiaka-zy/materials/3c28619290414e552e988e09b3675b72.mp4', 5.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '东鹏冠珠马可波罗' AND level = 3), '182e4c8bbcea8f103672b147b4606213', 'https://media.liche.cn/meijiaka-zy/materials/182e4c8bbcea8f103672b147b4606213.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '九牧恒洁箭牌' AND level = 3), '7d5607ab1886ba948fc1e94398473274', 'https://media.liche.cn/meijiaka-zy/materials/7d5607ab1886ba948fc1e94398473274.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '九牧箭牌潜水艇' AND level = 3), '6924bfd00653c3c6cfcb2d1d02c4789c', 'https://media.liche.cn/meijiaka-zy/materials/6924bfd00653c3c6cfcb2d1d02c4789c.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '乳胶漆买谁家' AND level = 3), '6086a32ec41db26e5bc570f1f27c1fbc', 'https://media.liche.cn/meijiaka-zy/materials/6086a32ec41db26e5bc570f1f27c1fbc.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '公牛施耐德西门子' AND level = 3), 'c0a3e230b32026b78596c192718345cb', 'https://media.liche.cn/meijiaka-zy/materials/c0a3e230b32026b78596c192718345cb.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '冰箱买谁家' AND level = 3), 'fad1e564d3272515eab8dd75079870de', 'https://media.liche.cn/meijiaka-zy/materials/fad1e564d3272515eab8dd75079870de.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '厨卫五金谁家好' AND level = 3), '4d20e0593c973366e064451fd9561eff', 'https://media.liche.cn/meijiaka-zy/materials/4d20e0593c973366e064451fd9561eff.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '吊顶选谁家' AND level = 3), '4ee89978139e0e55c809aedf5a56ddc2', 'https://media.liche.cn/meijiaka-zy/materials/4ee89978139e0e55c809aedf5a56ddc2.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '圣象世友大自然' AND level = 3), '5c78732634c008867211a9a34d124881', 'https://media.liche.cn/meijiaka-zy/materials/5c78732634c008867211a9a34d124881.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '地板哪家好' AND level = 3), '647972fffa483aa807ecd08ed53219be', 'https://media.liche.cn/meijiaka-zy/materials/647972fffa483aa807ecd08ed53219be.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '地漏谁家好' AND level = 3), 'd4fb5c1a8bf3cecf8662f82b6977a954', 'https://media.liche.cn/meijiaka-zy/materials/d4fb5c1a8bf3cecf8662f82b6977a954.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '奥普友邦法狮龙' AND level = 3), 'a6cc0fb2a45ea0e4b988451baddac499', 'https://media.liche.cn/meijiaka-zy/materials/a6cc0fb2a45ea0e4b988451baddac499.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家装水泥谁家好' AND level = 3), 'e189e0507cd2ecb0be2e32d2cf65dccd', 'https://media.liche.cn/meijiaka-zy/materials/e189e0507cd2ecb0be2e32d2cf65dccd.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家装水管谁家好' AND level = 3), '72d9643978717084039cf3507f9bdd04', 'https://media.liche.cn/meijiaka-zy/materials/72d9643978717084039cf3507f9bdd04.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '开关插座买谁家' AND level = 3), '8df9cfec100cea2661784361571a3a11', 'https://media.liche.cn/meijiaka-zy/materials/8df9cfec100cea2661784361571a3a11.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '德高西卡马贝' AND level = 3), 'b365eb193c1ede5777cc04d2427ea0e7', 'https://media.liche.cn/meijiaka-zy/materials/b365eb193c1ede5777cc04d2427ea0e7.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '方太老板华帝' AND level = 3), '9e37037aad90b25493228d05c0405696', 'https://media.liche.cn/meijiaka-zy/materials/9e37037aad90b25493228d05c0405696.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '日丰伟星保利' AND level = 3), '3318c054d10f5ecca8ce397f435c01af', 'https://media.liche.cn/meijiaka-zy/materials/3318c054d10f5ecca8ce397f435c01af.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '板材选谁家' AND level = 3), '9e5eb608644425a51613e2e145ba28e0', 'https://media.liche.cn/meijiaka-zy/materials/9e5eb608644425a51613e2e145ba28e0.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '水管买谁家' AND level = 3), '0d37b9dbf4b44858f16f155ba88a7054', 'https://media.liche.cn/meijiaka-zy/materials/0d37b9dbf4b44858f16f155ba88a7054.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '海尔美的卡萨帝' AND level = 3), '33e3a3ae93f65e72d055431b0d132495', 'https://media.liche.cn/meijiaka-zy/materials/33e3a3ae93f65e72d055431b0d132495.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '海螺红狮中联' AND level = 3), 'cd7f119729a062df350940bb003f873d', 'https://media.liche.cn/meijiaka-zy/materials/cd7f119729a062df350940bb003f873d.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '烟机哪家好' AND level = 3), '01690f5d76a40142f365da61319c9f31', 'https://media.liche.cn/meijiaka-zy/materials/01690f5d76a40142f365da61319c9f31.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '玻璃胶谁家好' AND level = 3), '52d7c9db8291af1d9e2061c3288bec2b', 'https://media.liche.cn/meijiaka-zy/materials/52d7c9db8291af1d9e2061c3288bec2b.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '瓦克西卡百得' AND level = 3), '1e2774b366631016acecc03c322dc0a2', 'https://media.liche.cn/meijiaka-zy/materials/1e2774b366631016acecc03c322dc0a2.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '瓷砖哪家好' AND level = 3), 'e727f0ea33030c14d33185329794398c', 'https://media.liche.cn/meijiaka-zy/materials/e727f0ea33030c14d33185329794398c.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '瓷砖胶谁家好' AND level = 3), '07a1f9a9ec09809d33781a2b6265ff48', 'https://media.liche.cn/meijiaka-zy/materials/07a1f9a9ec09809d33781a2b6265ff48.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '电线买谁家' AND level = 3), '04f61f5a57454799d2aa1000764311af', 'https://media.liche.cn/meijiaka-zy/materials/04f61f5a57454799d2aa1000764311af.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '电视买谁家' AND level = 3), '82c400fbc27c42dd8992458d2e94c047', 'https://media.liche.cn/meijiaka-zy/materials/82c400fbc27c42dd8992458d2e94c047.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '石膏板谁家好' AND level = 3), 'e6469a2dc66350c330d2d87f08a9cd5a', 'https://media.liche.cn/meijiaka-zy/materials/e6469a2dc66350c330d2d87f08a9cd5a.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '科勒九牧汉斯格雅' AND level = 3), '80506a9eb5e1a06d3c5cb98eaae515cd', 'https://media.liche.cn/meijiaka-zy/materials/80506a9eb5e1a06d3c5cb98eaae515cd.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '立邦三棵树多乐士' AND level = 3), '82b26195cdb7a08793abf3ff17d400eb', 'https://media.liche.cn/meijiaka-zy/materials/82b26195cdb7a08793abf3ff17d400eb.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '立邦德高东方雨虹' AND level = 3), '03602a66190ad519f81c70a80e6cd0d2', 'https://media.liche.cn/meijiaka-zy/materials/03602a66190ad519f81c70a80e6cd0d2.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '立邦美巢圣戈邦' AND level = 3), 'cc00321964988a29315468e4dca53d06', 'https://media.liche.cn/meijiaka-zy/materials/cc00321964988a29315468e4dca53d06.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '索尼海信TCL' AND level = 3), 'fb9d3b062be7ed44fef7ec81490a4963', 'https://media.liche.cn/meijiaka-zy/materials/fb9d3b062be7ed44fef7ec81490a4963.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '腻子粉哪家好' AND level = 3), '887c5ea3238d2c1196eb09c410dc8f7f', 'https://media.liche.cn/meijiaka-zy/materials/887c5ea3238d2c1196eb09c410dc8f7f.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '花洒哪家好' AND level = 3), 'f6d4592e08482cb903daca04d432f3ed', 'https://media.liche.cn/meijiaka-zy/materials/f6d4592e08482cb903daca04d432f3ed.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '远东宝胜熊猫' AND level = 3), 'c5ac8d8ff5435e123c8016657fbf955c', 'https://media.liche.cn/meijiaka-zy/materials/c5ac8d8ff5435e123c8016657fbf955c.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '金牛伟星日丰' AND level = 3), '3c9546527a38c300050ed28bda81e204', 'https://media.liche.cn/meijiaka-zy/materials/3c9546527a38c300050ed28bda81e204.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '防水买谁家' AND level = 3), '3e7c5b554836376605828f374bd15ae5', 'https://media.liche.cn/meijiaka-zy/materials/3e7c5b554836376605828f374bd15ae5.mp4', 3.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '龙牌泰山可耐福' AND level = 3), '6589ffbf04c596583d2d2316216c7428', 'https://media.liche.cn/meijiaka-zy/materials/6589ffbf04c596583d2d2316216c7428.mp4', 5.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '488d5a9ac72bf8e9a2a574284f2bdded', 'https://media.liche.cn/meijiaka-zy/materials/488d5a9ac72bf8e9a2a574284f2bdded.mp4', 10.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '3c716b567964591569abfc8d16e7ff9b', 'https://media.liche.cn/meijiaka-zy/materials/3c716b567964591569abfc8d16e7ff9b.mp4', 9.97, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '2fb5183ef1547fb3d7d4d8e56fe5154a', 'https://media.liche.cn/meijiaka-zy/materials/2fb5183ef1547fb3d7d4d8e56fe5154a.mp4', 10.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '0d7081072e409e8f2c7d3a61a793f348', 'https://media.liche.cn/meijiaka-zy/materials/0d7081072e409e8f2c7d3a61a793f348.mp4', 10.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), 'f083bfca1800c171af2dfc767fc5d28a', 'https://media.liche.cn/meijiaka-zy/materials/f083bfca1800c171af2dfc767fc5d28a.mp4', 8.48, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '8e198970fe0be12c9067fefe658d1cdd', 'https://media.liche.cn/meijiaka-zy/materials/8e198970fe0be12c9067fefe658d1cdd.mp4', 9.8, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '3763505e431dc39a9fef135ad82ee6f1', 'https://media.liche.cn/meijiaka-zy/materials/3763505e431dc39a9fef135ad82ee6f1.mp4', 9.92, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '0576abe034e932071d7c3b67104e79c3', 'https://media.liche.cn/meijiaka-zy/materials/0576abe034e932071d7c3b67104e79c3.mp4', 9.9, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), '07281a59949dcaa72c22b54b8569e1ea', 'https://media.liche.cn/meijiaka-zy/materials/07281a59949dcaa72c22b54b8569e1ea.mp4', 4.71, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '装烟机灶具-主材安装镜' AND level = 3), 'e8d1429ec925636603b69b57ca3eba52', 'https://media.liche.cn/meijiaka-zy/materials/e8d1429ec925636603b69b57ca3eba52.mp4', 4.09, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '9d516288fc104f41e3a4c3747883a072', 'https://media.liche.cn/meijiaka-zy/materials/9d516288fc104f41e3a4c3747883a072.mp4', 6.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '8b293fcabbf5e8dc2f84a77e9cbb9956', 'https://media.liche.cn/meijiaka-zy/materials/8b293fcabbf5e8dc2f84a77e9cbb9956.mp4', 6.18, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '432a789688f8f729ec72ccbf8571820a', 'https://media.liche.cn/meijiaka-zy/materials/432a789688f8f729ec72ccbf8571820a.mp4', 10.0, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '3a97f3ebd82b3ff8c04ec47871199159', 'https://media.liche.cn/meijiaka-zy/materials/3a97f3ebd82b3ff8c04ec47871199159.mp4', 5.62, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), 'a67d0a41c10ea002968fb0ed1ad8ae0e', 'https://media.liche.cn/meijiaka-zy/materials/a67d0a41c10ea002968fb0ed1ad8ae0e.mp4', 8.55, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '6b28e44d37a14c3d9ac8b503a29a421c', 'https://media.liche.cn/meijiaka-zy/materials/6b28e44d37a14c3d9ac8b503a29a421c.mp4', 8.92, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), '9468e8aba0f47eeef9bc59e395bfcc72', 'https://media.liche.cn/meijiaka-zy/materials/9468e8aba0f47eeef9bc59e395bfcc72.mp4', 10.2, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '封窗施工-封窗镜' AND level = 3), 'b5d109f43246296ca6de51d28e596dcd', 'https://media.liche.cn/meijiaka-zy/materials/b5d109f43246296ca6de51d28e596dcd.mp4', 10.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), 'a15878e831df63d8cffc1066bf25e257', 'https://media.liche.cn/meijiaka-zy/materials/a15878e831df63d8cffc1066bf25e257.mp4', 7.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '1622140bd7229107b38927b831f8bea8', 'https://media.liche.cn/meijiaka-zy/materials/1622140bd7229107b38927b831f8bea8.mp4', 10.01, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '5ef57acfda494cfdfb5185594c51364c', 'https://media.liche.cn/meijiaka-zy/materials/5ef57acfda494cfdfb5185594c51364c.mp4', 7.85, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '4473c9736c25e77375459bd2968f4753', 'https://media.liche.cn/meijiaka-zy/materials/4473c9736c25e77375459bd2968f4753.mp4', 6.11, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '67526f381c629710d78c53ec3a2f6941', 'https://media.liche.cn/meijiaka-zy/materials/67526f381c629710d78c53ec3a2f6941.mp4', 5.2, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '1690725fa66d82b9400e462839328658', 'https://media.liche.cn/meijiaka-zy/materials/1690725fa66d82b9400e462839328658.mp4', 7.41, 0, 'active', NOW(), NOW()),
|
||||
((SELECT id FROM mjk_broll_categories WHERE name = '家具进场摆放就位-软装进场镜' AND level = 3), '28b67c0a7565ff259f889456334d000d', 'https://media.liche.cn/meijiaka-zy/materials/28b67c0a7565ff259f889456334d000d.mp4', 9.45, 0, 'active', NOW(), NOW());
|
||||
Executable
+203
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
# 新增素材6.2 批量上传脚本
|
||||
|
||||
# 万华爱格兔宝宝 (5.0s)
|
||||
qshell fput meijiaka-zy materials/3c28619290414e552e988e09b3675b72.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/万华爱格兔宝宝/3c28619290414e552e988e09b3675b72.mp4'
|
||||
|
||||
# 东鹏冠珠马可波罗 (5.01s)
|
||||
qshell fput meijiaka-zy materials/182e4c8bbcea8f103672b147b4606213.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/东鹏冠珠马可波罗/182e4c8bbcea8f103672b147b4606213.mp4'
|
||||
|
||||
# 九牧恒洁箭牌 (5.01s)
|
||||
qshell fput meijiaka-zy materials/7d5607ab1886ba948fc1e94398473274.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/九牧恒洁箭牌/7d5607ab1886ba948fc1e94398473274.mp4'
|
||||
|
||||
# 九牧箭牌潜水艇 (5.01s)
|
||||
qshell fput meijiaka-zy materials/6924bfd00653c3c6cfcb2d1d02c4789c.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/九牧箭牌潜水艇/6924bfd00653c3c6cfcb2d1d02c4789c.mp4'
|
||||
|
||||
# 乳胶漆买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/6086a32ec41db26e5bc570f1f27c1fbc.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/乳胶漆买谁家/6086a32ec41db26e5bc570f1f27c1fbc.mp4'
|
||||
|
||||
# 公牛施耐德西门子 (5.01s)
|
||||
qshell fput meijiaka-zy materials/c0a3e230b32026b78596c192718345cb.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/公牛施耐德西门子/c0a3e230b32026b78596c192718345cb.mp4'
|
||||
|
||||
# 冰箱买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/fad1e564d3272515eab8dd75079870de.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/冰箱买谁家/fad1e564d3272515eab8dd75079870de.mp4'
|
||||
|
||||
# 厨卫五金谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/4d20e0593c973366e064451fd9561eff.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/厨卫五金谁家好/4d20e0593c973366e064451fd9561eff.mp4'
|
||||
|
||||
# 吊顶选谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/4ee89978139e0e55c809aedf5a56ddc2.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/吊顶选谁家/4ee89978139e0e55c809aedf5a56ddc2.mp4'
|
||||
|
||||
# 圣象世友大自然 (5.01s)
|
||||
qshell fput meijiaka-zy materials/5c78732634c008867211a9a34d124881.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/圣象世友大自然/5c78732634c008867211a9a34d124881.mp4'
|
||||
|
||||
# 地板哪家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/647972fffa483aa807ecd08ed53219be.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/地板哪家好/647972fffa483aa807ecd08ed53219be.mp4'
|
||||
|
||||
# 地漏谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/d4fb5c1a8bf3cecf8662f82b6977a954.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/地漏谁家好/d4fb5c1a8bf3cecf8662f82b6977a954.mp4'
|
||||
|
||||
# 奥普友邦法狮龙 (5.01s)
|
||||
qshell fput meijiaka-zy materials/a6cc0fb2a45ea0e4b988451baddac499.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/奥普友邦法狮龙/a6cc0fb2a45ea0e4b988451baddac499.mp4'
|
||||
|
||||
# 家装水泥谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/e189e0507cd2ecb0be2e32d2cf65dccd.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/家装水泥谁家好/e189e0507cd2ecb0be2e32d2cf65dccd.mp4'
|
||||
|
||||
# 家装水管谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/72d9643978717084039cf3507f9bdd04.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/家装水管谁家好/72d9643978717084039cf3507f9bdd04.mp4'
|
||||
|
||||
# 开关插座买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/8df9cfec100cea2661784361571a3a11.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/开关插座买谁家/8df9cfec100cea2661784361571a3a11.mp4'
|
||||
|
||||
# 德高西卡马贝 (5.01s)
|
||||
qshell fput meijiaka-zy materials/b365eb193c1ede5777cc04d2427ea0e7.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/德高西卡马贝/b365eb193c1ede5777cc04d2427ea0e7.mp4'
|
||||
|
||||
# 方太老板华帝 (5.01s)
|
||||
qshell fput meijiaka-zy materials/9e37037aad90b25493228d05c0405696.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/方太老板华帝/9e37037aad90b25493228d05c0405696.mp4'
|
||||
|
||||
# 日丰伟星保利 (5.01s)
|
||||
qshell fput meijiaka-zy materials/3318c054d10f5ecca8ce397f435c01af.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/日丰伟星保利/3318c054d10f5ecca8ce397f435c01af.mp4'
|
||||
|
||||
# 板材选谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/9e5eb608644425a51613e2e145ba28e0.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/板材选谁家/9e5eb608644425a51613e2e145ba28e0.mp4'
|
||||
|
||||
# 水管买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/0d37b9dbf4b44858f16f155ba88a7054.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/水管买谁家/0d37b9dbf4b44858f16f155ba88a7054.mp4'
|
||||
|
||||
# 海尔美的卡萨帝 (5.01s)
|
||||
qshell fput meijiaka-zy materials/33e3a3ae93f65e72d055431b0d132495.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/海尔美的卡萨帝/33e3a3ae93f65e72d055431b0d132495.mp4'
|
||||
|
||||
# 海螺红狮中联 (5.01s)
|
||||
qshell fput meijiaka-zy materials/cd7f119729a062df350940bb003f873d.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/海螺红狮中联/cd7f119729a062df350940bb003f873d.mp4'
|
||||
|
||||
# 烟机哪家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/01690f5d76a40142f365da61319c9f31.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/烟机哪家好/01690f5d76a40142f365da61319c9f31.mp4'
|
||||
|
||||
# 玻璃胶谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/52d7c9db8291af1d9e2061c3288bec2b.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/玻璃胶谁家好/52d7c9db8291af1d9e2061c3288bec2b.mp4'
|
||||
|
||||
# 瓦克西卡百得 (5.01s)
|
||||
qshell fput meijiaka-zy materials/1e2774b366631016acecc03c322dc0a2.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/瓦克西卡百得/1e2774b366631016acecc03c322dc0a2.mp4'
|
||||
|
||||
# 瓷砖哪家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/e727f0ea33030c14d33185329794398c.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/瓷砖哪家好/e727f0ea33030c14d33185329794398c.mp4'
|
||||
|
||||
# 瓷砖胶谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/07a1f9a9ec09809d33781a2b6265ff48.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/瓷砖胶谁家好/07a1f9a9ec09809d33781a2b6265ff48.mp4'
|
||||
|
||||
# 电线买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/04f61f5a57454799d2aa1000764311af.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/电线买谁家/04f61f5a57454799d2aa1000764311af.mp4'
|
||||
|
||||
# 电视买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/82c400fbc27c42dd8992458d2e94c047.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/电视买谁家/82c400fbc27c42dd8992458d2e94c047.mp4'
|
||||
|
||||
# 石膏板谁家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/e6469a2dc66350c330d2d87f08a9cd5a.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/石膏板谁家好/e6469a2dc66350c330d2d87f08a9cd5a.mp4'
|
||||
|
||||
# 科勒九牧汉斯格雅 (5.01s)
|
||||
qshell fput meijiaka-zy materials/80506a9eb5e1a06d3c5cb98eaae515cd.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/科勒九牧汉斯格雅/80506a9eb5e1a06d3c5cb98eaae515cd.mp4'
|
||||
|
||||
# 立邦三棵树多乐士 (5.01s)
|
||||
qshell fput meijiaka-zy materials/82b26195cdb7a08793abf3ff17d400eb.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/立邦三棵树多乐士/82b26195cdb7a08793abf3ff17d400eb.mp4'
|
||||
|
||||
# 立邦德高东方雨虹 (5.01s)
|
||||
qshell fput meijiaka-zy materials/03602a66190ad519f81c70a80e6cd0d2.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/立邦德高东方雨虹/03602a66190ad519f81c70a80e6cd0d2.mp4'
|
||||
|
||||
# 立邦美巢圣戈邦 (5.01s)
|
||||
qshell fput meijiaka-zy materials/cc00321964988a29315468e4dca53d06.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/立邦美巢圣戈邦/cc00321964988a29315468e4dca53d06.mp4'
|
||||
|
||||
# 索尼海信TCL (5.01s)
|
||||
qshell fput meijiaka-zy materials/fb9d3b062be7ed44fef7ec81490a4963.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/索尼海信TCL/fb9d3b062be7ed44fef7ec81490a4963.mp4'
|
||||
|
||||
# 腻子粉哪家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/887c5ea3238d2c1196eb09c410dc8f7f.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/腻子粉哪家好/887c5ea3238d2c1196eb09c410dc8f7f.mp4'
|
||||
|
||||
# 花洒哪家好 (3.0s)
|
||||
qshell fput meijiaka-zy materials/f6d4592e08482cb903daca04d432f3ed.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/花洒哪家好/f6d4592e08482cb903daca04d432f3ed.mp4'
|
||||
|
||||
# 远东宝胜熊猫 (5.01s)
|
||||
qshell fput meijiaka-zy materials/c5ac8d8ff5435e123c8016657fbf955c.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/远东宝胜熊猫/c5ac8d8ff5435e123c8016657fbf955c.mp4'
|
||||
|
||||
# 金牛伟星日丰 (5.01s)
|
||||
qshell fput meijiaka-zy materials/3c9546527a38c300050ed28bda81e204.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/金牛伟星日丰/3c9546527a38c300050ed28bda81e204.mp4'
|
||||
|
||||
# 防水买谁家 (3.0s)
|
||||
qshell fput meijiaka-zy materials/3e7c5b554836376605828f374bd15ae5.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/防水买谁家/3e7c5b554836376605828f374bd15ae5.mp4'
|
||||
|
||||
# 龙牌泰山可耐福 (5.01s)
|
||||
qshell fput meijiaka-zy materials/6589ffbf04c596583d2d2316216c7428.mp4 '/Users/0fun/Downloads/新增素材6.2/其他/装修材料选择/龙牌泰山可耐福/6589ffbf04c596583d2d2316216c7428.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (10.01s)
|
||||
qshell fput meijiaka-zy materials/488d5a9ac72bf8e9a2a574284f2bdded.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/488d5a9ac72bf8e9a2a574284f2bdded.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (9.97s)
|
||||
qshell fput meijiaka-zy materials/3c716b567964591569abfc8d16e7ff9b.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/3c716b567964591569abfc8d16e7ff9b.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (10.01s)
|
||||
qshell fput meijiaka-zy materials/2fb5183ef1547fb3d7d4d8e56fe5154a.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/2fb5183ef1547fb3d7d4d8e56fe5154a.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (10.01s)
|
||||
qshell fput meijiaka-zy materials/0d7081072e409e8f2c7d3a61a793f348.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/0d7081072e409e8f2c7d3a61a793f348.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (8.48s)
|
||||
qshell fput meijiaka-zy materials/f083bfca1800c171af2dfc767fc5d28a.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/f083bfca1800c171af2dfc767fc5d28a.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (9.8s)
|
||||
qshell fput meijiaka-zy materials/8e198970fe0be12c9067fefe658d1cdd.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/8e198970fe0be12c9067fefe658d1cdd.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (9.92s)
|
||||
qshell fput meijiaka-zy materials/3763505e431dc39a9fef135ad82ee6f1.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/3763505e431dc39a9fef135ad82ee6f1.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (9.9s)
|
||||
qshell fput meijiaka-zy materials/0576abe034e932071d7c3b67104e79c3.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/0576abe034e932071d7c3b67104e79c3.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (4.71s)
|
||||
qshell fput meijiaka-zy materials/07281a59949dcaa72c22b54b8569e1ea.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/07281a59949dcaa72c22b54b8569e1ea.mp4'
|
||||
|
||||
# 装烟机灶具-主材安装镜 (4.09s)
|
||||
qshell fput meijiaka-zy materials/e8d1429ec925636603b69b57ca3eba52.mp4 '/Users/0fun/Downloads/新增素材6.2/安装收尾类/电器安装/装烟机灶具/e8d1429ec925636603b69b57ca3eba52.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (6.01s)
|
||||
qshell fput meijiaka-zy materials/9d516288fc104f41e3a4c3747883a072.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/9d516288fc104f41e3a4c3747883a072.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (6.18s)
|
||||
qshell fput meijiaka-zy materials/8b293fcabbf5e8dc2f84a77e9cbb9956.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/8b293fcabbf5e8dc2f84a77e9cbb9956.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (10.0s)
|
||||
qshell fput meijiaka-zy materials/432a789688f8f729ec72ccbf8571820a.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/432a789688f8f729ec72ccbf8571820a.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (5.62s)
|
||||
qshell fput meijiaka-zy materials/3a97f3ebd82b3ff8c04ec47871199159.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/3a97f3ebd82b3ff8c04ec47871199159.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (8.55s)
|
||||
qshell fput meijiaka-zy materials/a67d0a41c10ea002968fb0ed1ad8ae0e.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/a67d0a41c10ea002968fb0ed1ad8ae0e.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (8.92s)
|
||||
qshell fput meijiaka-zy materials/6b28e44d37a14c3d9ac8b503a29a421c.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/6b28e44d37a14c3d9ac8b503a29a421c.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (10.2s)
|
||||
qshell fput meijiaka-zy materials/9468e8aba0f47eeef9bc59e395bfcc72.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/9468e8aba0f47eeef9bc59e395bfcc72.mp4'
|
||||
|
||||
# 封窗施工-封窗镜 (10.01s)
|
||||
qshell fput meijiaka-zy materials/b5d109f43246296ca6de51d28e596dcd.mp4 '/Users/0fun/Downloads/新增素材6.2/拆改改造类/封窗/封窗施工/b5d109f43246296ca6de51d28e596dcd.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (7.01s)
|
||||
qshell fput meijiaka-zy materials/a15878e831df63d8cffc1066bf25e257.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/a15878e831df63d8cffc1066bf25e257.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (10.01s)
|
||||
qshell fput meijiaka-zy materials/1622140bd7229107b38927b831f8bea8.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/1622140bd7229107b38927b831f8bea8.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (7.85s)
|
||||
qshell fput meijiaka-zy materials/5ef57acfda494cfdfb5185594c51364c.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/5ef57acfda494cfdfb5185594c51364c.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (6.11s)
|
||||
qshell fput meijiaka-zy materials/4473c9736c25e77375459bd2968f4753.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/4473c9736c25e77375459bd2968f4753.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (5.2s)
|
||||
qshell fput meijiaka-zy materials/67526f381c629710d78c53ec3a2f6941.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/67526f381c629710d78c53ec3a2f6941.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (7.41s)
|
||||
qshell fput meijiaka-zy materials/1690725fa66d82b9400e462839328658.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/1690725fa66d82b9400e462839328658.mp4'
|
||||
|
||||
# 家具进场摆放就位-软装进场镜 (9.45s)
|
||||
qshell fput meijiaka-zy materials/28b67c0a7565ff259f889456334d000d.mp4 '/Users/0fun/Downloads/新增素材6.2/软装完工&验收类/软装进场镜/家具进场摆放就位-软装进场/28b67c0a7565ff259f889456334d000d.mp4'
|
||||
Generated
+1
-1
@@ -4219,7 +4219,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-app"
|
||||
version = "1.7.0"
|
||||
version = "1.7.1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::ApiResponse;
|
||||
use crate::storage::voice as voice_storage;
|
||||
use tauri::Manager;
|
||||
|
||||
// --------------------- 音色素材库命令 ---------------------
|
||||
|
||||
@@ -169,6 +170,70 @@ pub async fn extract_audio_segment(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从本地视频文件中提取音频(MP4 → MP3)
|
||||
*
|
||||
* 输出文件自动生成在 app_local_data_dir/temp/ 下。
|
||||
* @param input_path 本地视频文件路径(需在 app_local_data_dir 下)
|
||||
* @returns 提取后的 MP3 文件路径
|
||||
*/
|
||||
#[tauri::command]
|
||||
pub async fn extract_audio_from_video(
|
||||
app: tauri::AppHandle,
|
||||
input_path: String,
|
||||
) -> ApiResponse<String> {
|
||||
// 验证输入路径安全
|
||||
let safe_input = match crate::ffmpeg_cmd::sanitize_output_path(&input_path) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
return ApiResponse {
|
||||
code: 500,
|
||||
message: format!("路径验证失败: {}", e),
|
||||
data: None,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 生成输出路径:app_local_data_dir/temp/extracted_{uuid}.mp3
|
||||
let output_path = match app.path().app_local_data_dir() {
|
||||
Ok(dir) => {
|
||||
let temp_dir = dir.join("temp");
|
||||
if let Err(e) = std::fs::create_dir_all(&temp_dir) {
|
||||
return ApiResponse {
|
||||
code: 500,
|
||||
message: format!("创建临时目录失败: {}", e),
|
||||
data: None,
|
||||
};
|
||||
}
|
||||
temp_dir.join(format!("extracted_{}.mp3", uuid::Uuid::new_v4()))
|
||||
}
|
||||
Err(e) => {
|
||||
return ApiResponse {
|
||||
code: 500,
|
||||
message: format!("获取应用目录失败: {}", e),
|
||||
data: None,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
match crate::ffmpeg_cmd::extract_audio_from_video(
|
||||
&app,
|
||||
&safe_input,
|
||||
&output_path.to_string_lossy(),
|
||||
).await {
|
||||
Ok(_) => ApiResponse {
|
||||
code: 200,
|
||||
message: "音频提取成功".to_string(),
|
||||
data: Some(output_path.to_string_lossy().to_string()),
|
||||
},
|
||||
Err(e) => ApiResponse {
|
||||
code: 500,
|
||||
message: format!("音频提取失败: {}", e),
|
||||
data: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// 上传本地音频文件到后端,后端上传到七牛云并返回 URL
|
||||
#[tauri::command]
|
||||
pub async fn upload_audio_file(
|
||||
|
||||
@@ -826,6 +826,33 @@ pub async fn extract_audio_segment(
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 从视频中提取音频(完整时长)
|
||||
*
|
||||
* 将视频文件的音轨提取为 MP3 格式,输出到指定路径。
|
||||
* 适用于 MP4 → MP3 转换,供声音复刻使用。
|
||||
*/
|
||||
pub async fn extract_audio_from_video(
|
||||
app: &AppHandle,
|
||||
input_path: &str,
|
||||
output_path: &str,
|
||||
) -> Result<(), String> {
|
||||
let safe_input = validate_safe_path(input_path)?;
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let args = vec![
|
||||
"-i".to_string(), safe_input,
|
||||
"-vn".to_string(), // 去掉视频
|
||||
"-c:a".to_string(), "libmp3lame".to_string(),
|
||||
"-b:a".to_string(), "192k".to_string(),
|
||||
"-ar".to_string(), "44100".to_string(),
|
||||
"-ac".to_string(), "2".to_string(),
|
||||
"-y".to_string(),
|
||||
safe_output,
|
||||
];
|
||||
run_ffmpeg(app, args).await.map(|_| ())
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 ffprobe 返回的帧率字符串(如 "30000/1001" 或 "30/1")
|
||||
*/
|
||||
|
||||
@@ -437,6 +437,7 @@ pub fn run() {
|
||||
// 音频管理
|
||||
commands::voice::save_audio,
|
||||
commands::voice::extract_audio_segment,
|
||||
commands::voice::extract_audio_from_video,
|
||||
commands::voice::upload_audio_file,
|
||||
// 音色素材库
|
||||
commands::voice::load_voice_materials,
|
||||
|
||||
@@ -196,3 +196,31 @@ export async function extractAudioSegment(args: ExtractAudioSegmentRequest): Pro
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/** 从本地视频文件中提取音频(MP4 → MP3)
|
||||
* @param inputPath 本地视频文件路径
|
||||
* @returns 提取后的 MP3 文件路径
|
||||
*/
|
||||
export async function extractAudioFromVideo(inputPath: string): Promise<string> {
|
||||
const result = await invoke<{ code: number; data?: string; message: string }>('extract_audio_from_video', {
|
||||
inputPath,
|
||||
});
|
||||
if (result.code !== 200 || !result.data) {
|
||||
throw new Error(result.message || '音频提取失败');
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/** 上传本地音频文件到后端(后端上传到七牛云)
|
||||
* @param localPath 本地音频文件路径
|
||||
* @returns 七牛云 URL
|
||||
*/
|
||||
export async function uploadLocalAudioFile(localPath: string): Promise<string> {
|
||||
const result = await invoke<{ code: number; data?: { url: string }; message: string }>('upload_audio_file', {
|
||||
localPath,
|
||||
});
|
||||
if (result.code !== 200 || !result.data?.url) {
|
||||
throw new Error(result.message || '上传音频失败');
|
||||
}
|
||||
return result.data.url;
|
||||
}
|
||||
|
||||
@@ -149,11 +149,44 @@ export default function VoiceMaterialLibrary() {
|
||||
return;
|
||||
}
|
||||
|
||||
const allowedExts = ['.mp3', '.m4a', '.wav'];
|
||||
const ext = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
|
||||
|
||||
if (!allowedExts.includes(ext)) {
|
||||
resolve({ valid: false, error: '仅支持 MP3、M4A、WAV 格式' });
|
||||
if (ext === '.mp4') {
|
||||
// MP4 文件:检查时长(10 秒 ~ 2 分钟)
|
||||
const video = document.createElement('video');
|
||||
video.preload = 'metadata';
|
||||
|
||||
video.onloadedmetadata = () => {
|
||||
const duration = video.duration;
|
||||
URL.revokeObjectURL(video.src);
|
||||
if (duration < 10) {
|
||||
resolve({ valid: false, error: `视频时长 ${duration.toFixed(1)} 秒,要求至少 10 秒` });
|
||||
return;
|
||||
}
|
||||
if (duration > 120) {
|
||||
resolve({ valid: false, error: `视频时长 ${duration.toFixed(1)} 秒,要求不超过 2 分钟` });
|
||||
return;
|
||||
}
|
||||
resolve({ valid: true });
|
||||
};
|
||||
|
||||
video.onerror = () => {
|
||||
URL.revokeObjectURL(video.src);
|
||||
resolve({ valid: false, error: '无法读取视频文件' });
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
URL.revokeObjectURL(video.src);
|
||||
resolve({ valid: false, error: '读取视频超时' });
|
||||
}, 8000);
|
||||
|
||||
video.src = URL.createObjectURL(file);
|
||||
return;
|
||||
}
|
||||
|
||||
const allowedAudioExts = ['.mp3', '.m4a', '.wav'];
|
||||
if (!allowedAudioExts.includes(ext)) {
|
||||
resolve({ valid: false, error: '仅支持 MP3、M4A、WAV、MP4 格式' });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -167,8 +200,8 @@ export default function VoiceMaterialLibrary() {
|
||||
resolve({ valid: false, error: `音频时长 ${duration.toFixed(1)} 秒,要求至少 10 秒` });
|
||||
return;
|
||||
}
|
||||
if (duration > 300) {
|
||||
resolve({ valid: false, error: `音频时长 ${duration.toFixed(1)} 秒,要求不超过 5 分钟` });
|
||||
if (duration > 120) {
|
||||
resolve({ valid: false, error: `音频时长 ${duration.toFixed(1)} 秒,要求不超过 2 分钟` });
|
||||
return;
|
||||
}
|
||||
resolve({ valid: true });
|
||||
@@ -316,8 +349,8 @@ export default function VoiceMaterialLibrary() {
|
||||
</svg>
|
||||
</div>
|
||||
<div className="voice-upload-text">
|
||||
<span className="voice-upload-title">上传音频样本</span>
|
||||
<span className="voice-upload-hint">MP3 / M4A / WAV,建议时长 10 秒 ~ 5 分钟</span>
|
||||
<span className="voice-upload-title">上传声音样本</span>
|
||||
<span className="voice-upload-hint">MP3 / M4A / WAV / MP4,建议时长 10 秒 ~ 2 分钟</span>
|
||||
</div>
|
||||
<div className="voice-upload-arrow">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
@@ -370,7 +403,7 @@ export default function VoiceMaterialLibrary() {
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept=".mp3,.m4a,.wav"
|
||||
accept=".mp3,.m4a,.wav,.mp4"
|
||||
onChange={handleFileSelect}
|
||||
style={{ display: 'none' }}
|
||||
/>
|
||||
@@ -385,7 +418,7 @@ export default function VoiceMaterialLibrary() {
|
||||
<div style={{ color: 'var(--text-secondary)' }}>
|
||||
<div style={{ fontSize: 'var(--font-sm)' }}>点击选择文件</div>
|
||||
<div style={{ fontSize: 'var(--font-xs)', marginTop: 6, lineHeight: 1.6 }}>
|
||||
支持 MP3 / M4A / WAV,人声干净无杂音,时长 10 秒 ~ 5 分钟,不超过 20MB
|
||||
支持 MP3 / M4A / WAV / MP4,人声干净无杂音,时长 10 秒 ~ 2 分钟,不超过 20MB
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import { create } from 'zustand';
|
||||
import type { VoiceInfo, VoiceMaterial } from '../api/modules/voice';
|
||||
import * as voiceApi from '../api/modules/voice';
|
||||
import { writeFile, remove, BaseDirectory } from '@tauri-apps/plugin-fs';
|
||||
import { join, appLocalDataDir } from '@tauri-apps/api/path';
|
||||
|
||||
interface VoiceState {
|
||||
// 预设音色列表
|
||||
@@ -128,31 +130,73 @@ export const useVoiceStore = create<VoiceState & VoiceActions>()(
|
||||
},
|
||||
|
||||
addVoiceMaterial: async (file: File, name: string) => {
|
||||
// 1. 上传七牛云
|
||||
const sourceUrl = await voiceApi.uploadAudio(file);
|
||||
let sourceUrl: string;
|
||||
let tempVideoPath = '';
|
||||
let tempMp3Path = '';
|
||||
|
||||
// 2. 提交 Vidu 同步克隆
|
||||
const cloneResult = await voiceApi.submitCloneTask({
|
||||
sourceAudioUrl: sourceUrl,
|
||||
voiceName: name,
|
||||
});
|
||||
try {
|
||||
const ext = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
|
||||
|
||||
// 3. Vidu 同步返回,直接 ready
|
||||
const material: VoiceMaterial = {
|
||||
id: cloneResult.voiceId || cloneResult.taskId,
|
||||
name,
|
||||
voiceId: cloneResult.voiceId || '',
|
||||
sourceUrl,
|
||||
trialUrl: cloneResult.trialUrl,
|
||||
status: 'ready',
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
if (ext === '.mp4') {
|
||||
// MP4 需要先本地提取音频
|
||||
tempVideoPath = await join('temp', `upload_${Date.now()}_${Math.random().toString(36).slice(2, 8)}.mp4`);
|
||||
|
||||
// 4. 保存到本地 JSON
|
||||
await voiceApi.saveVoiceMaterial(material);
|
||||
set(state => ({ voiceMaterials: [material, ...state.voiceMaterials] }));
|
||||
// 1a. 将 File 写入本地临时文件(使用 BaseDirectory.AppLocalData)
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const uint8Array = new Uint8Array(arrayBuffer);
|
||||
await writeFile(tempVideoPath, uint8Array, { baseDir: BaseDirectory.AppLocalData });
|
||||
|
||||
return material;
|
||||
// 1b. 调用 FFmpeg 提取音频(Rust 返回绝对路径)
|
||||
tempMp3Path = await voiceApi.extractAudioFromVideo(
|
||||
await join(await appLocalDataDir(), tempVideoPath)
|
||||
);
|
||||
|
||||
// 1c. 上传提取的 MP3
|
||||
sourceUrl = await voiceApi.uploadLocalAudioFile(tempMp3Path);
|
||||
} else {
|
||||
// 音频文件直接上传
|
||||
sourceUrl = await voiceApi.uploadAudio(file);
|
||||
}
|
||||
|
||||
// 2. 提交 Vidu 同步克隆
|
||||
const cloneResult = await voiceApi.submitCloneTask({
|
||||
sourceAudioUrl: sourceUrl,
|
||||
voiceName: name,
|
||||
});
|
||||
|
||||
// 3. Vidu 同步返回,直接 ready
|
||||
const material: VoiceMaterial = {
|
||||
id: cloneResult.voiceId || cloneResult.taskId,
|
||||
name,
|
||||
voiceId: cloneResult.voiceId || '',
|
||||
sourceUrl,
|
||||
trialUrl: cloneResult.trialUrl,
|
||||
status: 'ready',
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
// 4. 保存到本地 JSON
|
||||
await voiceApi.saveVoiceMaterial(material);
|
||||
set(state => ({ voiceMaterials: [material, ...state.voiceMaterials] }));
|
||||
|
||||
return material;
|
||||
} finally {
|
||||
// 清理临时文件
|
||||
if (tempVideoPath) {
|
||||
try {
|
||||
await remove(tempVideoPath, { baseDir: BaseDirectory.AppLocalData });
|
||||
} catch {
|
||||
// 忽略清理错误
|
||||
}
|
||||
}
|
||||
if (tempMp3Path) {
|
||||
try {
|
||||
await remove(tempMp3Path);
|
||||
} catch {
|
||||
// 忽略清理错误
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateVoiceMaterialStatus: (id: string, status: VoiceMaterial['status'], voiceId?: string, trialUrl?: string) => {
|
||||
|
||||
Reference in New Issue
Block a user