query_script 用来预览草稿脚本内容。你可以把它理解为:
draft_id这能帮助你在正式渲染或者下一步操作前,先检查数据是否完整、是否命中正确草稿。
请求体(JSON)最关键的是:
draft_id(必填):要查询的草稿 IDforce_update(可选,默认 true):是否强制刷新查询逻辑示例:
{
"draft_id": "dfd_xxx",
"force_update": true
}
如果不传 draft_id,接口会直接返回错误。
接口统一返回:
{
"success": false,
"output": "",
"error": ""
}
你重点看这 3 个字段:
success
true:查询成功false:查询失败output
error
判断顺序建议:
successsuccess=true 时看 outputsuccess=false 时看 errorquery_script 成功后,草稿 JSON 在 output 字段里。可以不落盘,直接转成 JSON 后查询。
jq '.success, .error' resp.json
jq -r '.output' resp.json | jq '{duration_us:.duration,duration_s:(.duration/1000000),fps:.fps}'
如果你不想落盘,后面的命令都可以写成这种形式:
jq '<你的查询表达式>' <(jq -r '.output' resp.json)
例如查询顶层字段:
jq 'keys' <(jq -r '.output' resp.json)
jq '{duration_us:.duration,duration_s:(.duration/1000000),fps:.fps,canvas:.canvas_config,project_video_mute:(.config.video_mute//false),track_count:(.tracks|length),material_group_count:(.materials|keys|length)}' <(jq -r '.output' resp.json)
怎么看:
duration_s/fps/canvas 看项目规格是否对project_video_mute 看是否全局静音track_count 看轨道是否完整jq 'keys' <(jq -r '.output' resp.json)
jq '.materials|keys' <(jq -r '.output' resp.json)
场景:看总时长、每轨覆盖范围、每段起止时间。
每轨时间覆盖与片段数:
jq '.tracks[] | .segments as $s | {track:.name,type,segment_count:($s|length),start_us:(if ($s|length)>0 then ($s|map(.target_timerange.start)|min) else null end),end_us:(if ($s|length)>0 then ($s|map(.target_timerange.start + .target_timerange.duration)|max) else null end),duration_us:(if ($s|length)>0 then (($s|map(.target_timerange.start + .target_timerange.duration)|max)-($s|map(.target_timerange.start)|min)) else 0 end)}' <(jq -r '.output' resp.json)
每个片段的开始/结束/素材真实长度:
jq 'def mats:[.materials|to_entries[]|select(.value|type=="array")|.key as $k|.value[]?|select(.id?)|{id,material_type:$k,material_duration_us:(.duration//null),material_name:(.name//.material_name//"")}]|map({key:.id,value:.})|from_entries; mats as $m|.tracks[] as $t|$t.segments[]?|{track:$t.name,type:$t.type,segment_id:.id,material_id,start_us:.target_timerange.start,end_us:(.target_timerange.start+.target_timerange.duration),segment_duration_us:.target_timerange.duration,source_duration_us:(.source_timerange.duration//null),speed:(.speed//1),material_duration_us:($m[.material_id].material_duration_us),material_type:($m[.material_id].material_type),material_name:($m[.material_id].material_name)}' <(jq -r '.output' resp.json)
场景:两个素材是否无缝衔接(间隙 <= 0.01 秒)。
jq -r '.tracks[] as $t|($t.segments|sort_by(.target_timerange.start)) as $s|range(0;($s|length)-1) as $i|($s[$i]) as $a|($s[$i+1]) as $b|($b.target_timerange.start-($a.target_timerange.start+$a.target_timerange.duration)) as $gap|[$t.name,$a.id,$b.id,($gap/1000000),($gap<=10000)]|@tsv' <(jq -r '.output' resp.json)
怎么看:
true:连续(满足你定义的阈值)< 0:说明发生重叠> 0.01:说明有可见空白场景:同一时间谁盖在上层。
jq '[.tracks|to_entries[] as $t|$t.value.segments[]?|{track_idx:$t.key,track:$t.value.name,type:$t.value.type,segment_id:.id,material_id,start_us:.target_timerange.start,end_us:(.target_timerange.start+.target_timerange.duration),track_render_index:(.track_render_index//0),render_index:(.render_index//0)}] | sort_by(.start_us,.track_render_index,.render_index)[]' <(jq -r '.output' resp.json)
怎么看:
track_render_index/render_index 越大越上层场景:轨道是否静音、单素材是否静音、音量是否异常。
说明:小于-60dB 即为静音。
轨道级静音检查:
jq 'def db(v): if v<=0 then -999 else (20*(v|log)/2.30258509299) end; .tracks[]|select(.type=="audio" or (.name|test("audio";"i")))|{track:.name,max_volume_linear:((.segments|map(.volume//1)|max)//1),max_volume_db:(((.segments|map(.volume//1)|max)//1)|db),track_muted:((((.segments|map(.volume//1)|max)//1)|db)<=-60)}' <(jq -r '.output' resp.json)
素材级静音检查:
jq 'def db(v): if v<=0 then -999 else (20*(v|log)/2.30258509299) end; .tracks[] as $t|$t.segments[]?|{track:$t.name,segment_id:.id,material_id,volume_linear:(.volume//1),volume_db:((.volume//1)|db),muted:(((.volume//1)|db)<=-60)}' <(jq -r '.output' resp.json)
场景:字幕字体、颜色、字号是否符合预期。
逐条查看:
jq '.materials.texts[]?| .content as $c | (try ($c|fromjson) catch {}) as $cj | {text_id:.id,text:($cj.text//""),font_size_field:.font_size,style_size:($cj.styles[0].size//null),font_path:($cj.styles[0].font.path//null),fill_rgb_0_1:($cj.styles[0].fill.content.solid.color//null),shadow_color:.shadow_color}' <(jq -r '.output' resp.json)
一致性检查(快速看是否“风格跑偏”):
jq '[.materials.texts[]?| .content as $c | (try ($c|fromjson) catch {}) as $cj | {font_path:($cj.styles[0].font.path//"unknown"),style_size:($cj.styles[0].size//null),fill:($cj.styles[0].fill.content.solid.color//null)}] | {font_path_set:([.[].font_path]|unique),style_size_set:([.[].style_size]|unique),fill_set:([.[].fill]|unique)}' <(jq -r '.output' resp.json)
场景:轨道片段引用了不存在的 material_id。
jq 'def mats:[.materials|to_entries[]|select(.value|type=="array")|.value[]?|select(.id?)|.id]|unique; mats as $ids|[.tracks[] as $t|$t.segments[]?|select((.material_id as $id|($ids|index($id)))==null)|{track:$t.name,segment_id:.id,missing_material_id:.material_id}]' <(jq -r '.output' resp.json)
怎么看:
success=falsejq -r '.error' resp.json
先查 draft_id 是否存在、是否命中同一环境草稿。
output 解析失败jq -r '.output' resp.json | jq 'keys'
报错通常说明 output 不是完整 JSON 字符串。
jq 'keys' <(jq -r '.output' resp.json)
jq '.materials|keys' <(jq -r '.output' resp.json)
jq '.tracks|length' <(jq -r '.output' resp.json)
先确认字段存在,再写具体过滤表达式。
1 秒 = 1000000。-60dB,方便批量判定和自动化比对。curl --location --request POST 'https://open.vectcut.com/cut_jianying/query_script' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"draft_id": "string",
"force_update": true
}'{
"error": "",
"output": "{\n \"canvas_config\": {\n \"width\": 1080,\n \"height\": 1920,\n \"ratio\": \"original\"\n },\n \"color_space\": 0,\n \"config\": {\n \"adjust_max_index\": 1,\n \"attachment_info\": [],\n \"combination_max_index\": 1,\n \"export_range\": null,\n \"extract_audio_last_index\": 1,\n \"lyrics_recognition_id\": \"\",\n \"lyrics_sync\": true,\n \"lyrics_taskinfo\": [],\n \"maintrack_adsorb\": true,\n \"material_save_mode\": 0,\n \"multi_language_current\": \"none\",\n \"multi_language_list\": [],\n \"multi_language_main\": \"none\",\n \"multi_language_mode\": \"none\",\n \"original_sound_last_index\": 1,\n \"record_audio_last_index\": 1,\n \"sticker_max_index\": 1,\n \"subtitle_keywords_config\": null,\n \"subtitle_recognition_id\": \"\",\n \"subtitle_sync\": true,\n \"subtitle_taskinfo\": [],\n \"system_font_list\": [],\n \"video_mute\": false,\n \"zoom_info_params\": null\n },\n \"cover\": null,\n \"create_time\": 0,\n \"duration\": 5366667,\n \"extra_info\": null,\n \"fps\": 30,\n \"free_render_index_mode_on\": false,\n \"group_container\": null,\n \"id\": \"91E08AC5-22FB-47e2-9AA0-7DC300FAEA2B\",\n \"keyframe_graph_list\": [],\n \"keyframes\": {\n \"adjusts\": [],\n \"audios\": [],\n \"effects\": [],\n \"filters\": [],\n \"handwrites\": [],\n \"stickers\": [],\n \"texts\": [],\n \"videos\": []\n },\n \"last_modified_platform\": {\n \"app_id\": 359289,\n \"app_source\": \"cc\",\n \"app_version\": \"6.5.0\",\n \"device_id\": \"c4ca4238a0b923820dcc509a6f75849b\",\n \"hard_disk_id\": \"307563e0192a94465c0e927fbc482942\",\n \"mac_address\": \"c3371f2d4fb02791c067ce44d8fb4ed5\",\n \"os\": \"mac\",\n \"os_version\": \"15.5\"\n },\n \"materials\": {\n \"ai_translates\": [],\n \"audio_balances\": [],\n \"audio_effects\": [],\n \"audio_fades\": [],\n \"audio_track_indexes\": [],\n \"audios\": [],\n \"beats\": [],\n \"canvases\": [],\n \"chromas\": [],\n \"color_curves\": [],\n \"digital_humans\": [],\n \"drafts\": [],\n \"effects\": [],\n \"flowers\": [],\n \"green_screens\": [],\n \"handwrites\": [],\n \"hsl\": [],\n \"images\": [],\n \"log_color_wheels\": [],\n \"loudnesses\": [],\n \"manual_deformations\": [],\n \"material_animations\": [],\n \"material_colors\": [],\n \"multi_language_refs\": [],\n \"placeholders\": [],\n \"plugin_effects\": [],\n \"primary_color_wheels\": [],\n \"realtime_denoises\": [],\n \"shapes\": [],\n \"smart_crops\": [],\n \"smart_relights\": [],\n \"sound_channel_mappings\": [],\n \"speeds\": [\n {\n \"curve_speed\": null,\n \"id\": \"33da1ce6b1634b9e8b100db706834c7b\",\n \"mode\": 0,\n \"speed\": 1.0,\n \"type\": \"speed\"\n }\n ],\n \"stickers\": [],\n \"tail_leaders\": [],\n \"text_templates\": [],\n \"texts\": [],\n \"time_marks\": [],\n \"transitions\": [],\n \"video_effects\": [],\n \"video_trackings\": [],\n \"videos\": [\n {\n \"audio_fade\": null,\n \"category_id\": \"\",\n \"category_name\": \"local\",\n \"check_flag\": 63487,\n \"crop\": {\n \"upper_left_x\": 0.0,\n \"upper_left_y\": 0.0,\n \"upper_right_x\": 1.0,\n \"upper_right_y\": 0.0,\n \"lower_left_x\": 0.0,\n \"lower_left_y\": 1.0,\n \"lower_right_x\": 1.0,\n \"lower_right_y\": 1.0\n },\n \"crop_ratio\": \"free\",\n \"crop_scale\": 1.0,\n \"duration\": 5366667,\n \"height\": 1280,\n \"id\": \"97ad098ba01b3bafb47ba6124d5c669a\",\n \"local_material_id\": \"\",\n \"material_id\": \"97ad098ba01b3bafb47ba6124d5c669a\",\n \"material_name\": \"video_6a455b81d53eb665.mp4\",\n \"media_path\": \"\",\n \"path\": \"\",\n \"remote_url\": \"https://cdn.wanx.aliyuncs.com/wanx/1719234057367822001/text_to_video/092faf3c94244973ab752ee1280ba76f.mp4?spm=5176.29623064.0.0.41ed26d6cBOhV3&file=092faf3c94244973ab752ee1280ba76f.mp4\",\n \"type\": \"video\",\n \"width\": 720\n }\n ],\n \"vocal_beautifys\": [],\n \"vocal_separations\": [],\n \"masks\": []\n },\n \"mutable_config\": null,\n \"name\": \"\",\n \"new_version\": \"110.0.0\",\n \"relationships\": [],\n \"render_index_track_mode_on\": true,\n \"retouch_cover\": null,\n \"source\": \"default\",\n \"static_cover_image_path\": \"\",\n \"time_marks\": null,\n \"tracks\": [\n {\n \"attribute\": 0,\n \"flag\": 0,\n \"id\": \"8f956c9e1822437ebf38c1c6592bd597\",\n \"is_default_name\": false,\n \"name\": \"main\",\n \"segments\": [],\n \"type\": \"video\"\n },\n {\n \"attribute\": 0,\n \"flag\": 0,\n \"id\": \"cd3ae172ff424442b81259d057eecf64\",\n \"is_default_name\": false,\n \"name\": \"video_main\",\n \"segments\": [\n {\n \"enable_adjust\": true,\n \"enable_color_correct_adjust\": false,\n \"enable_color_curves\": true,\n \"enable_color_match_adjust\": false,\n \"enable_color_wheels\": true,\n \"enable_lut\": true,\n \"enable_smart_color_adjust\": false,\n \"last_nonzero_volume\": 1.0,\n \"reverse\": false,\n \"track_attribute\": 0,\n \"track_render_index\": 0,\n \"visible\": true,\n \"id\": \"040cf233ce5147c5b0ef60adf0bc0007\",\n \"material_id\": \"97ad098ba01b3bafb47ba6124d5c669a\",\n \"target_timerange\": {\n \"start\": 0,\n \"duration\": 5366667\n },\n \"common_keyframes\": [],\n \"keyframe_refs\": [],\n \"source_timerange\": {\n \"start\": 0,\n \"duration\": 5366667\n },\n \"speed\": 1.0,\n \"volume\": 1.0,\n \"extra_material_refs\": [\n \"33da1ce6b1634b9e8b100db706834c7b\"\n ],\n \"clip\": {\n \"alpha\": 1.0,\n \"flip\": {\n \"horizontal\": false,\n \"vertical\": false\n },\n \"rotation\": 0.0,\n \"scale\": {\n \"x\": 1,\n \"y\": 1\n },\n \"transform\": {\n \"x\": 0,\n \"y\": 0\n }\n },\n \"uniform_scale\": {\n \"on\": true,\n \"value\": 1.0\n },\n \"hdr_settings\": {\n \"intensity\": 1.0,\n \"mode\": 1,\n \"nits\": 1000\n },\n \"render_index\": 0\n }\n ],\n \"type\": \"video\"\n }\n ],\n \"update_time\": 0,\n \"version\": 360000,\n \"platform\": {\n \"app_id\": 359289,\n \"app_source\": \"cc\",\n \"app_version\": \"6.5.0\",\n \"device_id\": \"c4ca4238a0b923820dcc509a6f75849b\",\n \"hard_disk_id\": \"307563e0192a94465c0e927fbc482942\",\n \"mac_address\": \"c3371f2d4fb02791c067ce44d8fb4ed5\",\n \"os\": \"mac\",\n \"os_version\": \"15.5\"\n }\n}",
"success": true
}