Build a Niwo short-video asset bundle from a conversation. Finalize the narration script with the user, download real images and B-roll footage from the web, trim clips with ffmpeg, write content.json and manifest.json, then deliver a zip the user uploads to Niwo for rendering. Requires downloading files to local disk, shell access with ffmpeg and ffprobe, and zip. Use when the user wants to turn a topic, news story, or finished script into a short video, or asks to gather footage and stills to match a narration.
Turn the content discussed with the user into an "asset bundle" that can be directly uploaded to Niwo for rendering into a video.
First Confirm If You Can Do This Task
This task requires the following three capabilities; if any one is missing, inform the user immediately and do not proceed forcefully:
Ability to access web pages online and download images and video files to local disk (not just provide links).
Ability to execute shell commands, with
ffmpeg
and
ffprobe
available in the environment.
Ability to package a local directory into a zip file and deliver it to the user.
If you can only search online but cannot download files (e.g., most mobile AI assistants), explain this directly and ask the user to switch to another tool.
Workflow
First, ask all questions about the video format and script requirements in one go as per "Step Zero". Only proceed after receiving the user's answers.
Finalize the narration script; for vertical info-style videos, finalize the hook headline along with the script.
Download images and B-roll footage.
Determine which seconds of each video clip to use.
Read
references/manifest-schema.md
before writing
manifest.json
.
Read
references/content-schema.md
before writing
content.json
.
Run
scripts/validate_bundle.py
for self-check; only package after passing the validation.
Deliverables
A zip file with the following structure after extraction:
You are only responsible for content: script, assets, pronunciation of polyphonic characters, hook headline. Rendering parameters such as video format, voice tone, speaking speed, subtitle toggle, IP character, and background music are selected by the user on Niwo's rendering interface before rendering; do not write them into
content.json
.
Step Zero: Confirm These Matters Before Starting
Before searching for assets or writing the script, clarify all the following questions. Do not make decisions on behalf of the user silently.
Only what the user explicitly states in this conversation counts as an answer. Cross-session memories, choices from previous videos, or inferences like "user's general preferences" do not count, even if you are certain. These can only be presented as recommended options for the user to confirm, not directly taken as conclusions.
Specifically, avoid opening with something like: "By default, I'll write it according to your usual 90-second format, targeting tech and business users with a strong hook" and then directly present a draft. You can place the 90-second option first and mark it as "Recommended", but the final choice must be confirmed by the user.
Only after the user explicitly says "You decide" (including selecting the option "I have no special requirements, please decide for me") can you make decisions on your own. Whenever a fallback default value is used, clearly list which values were used in your response; do not use them silently.
What to Ask: Five Independent Dimensions, All Asked in One Round
When the script is not finalized, the video format, target duration, audience, style/tone, and mandatory information points must all be asked in one round at once. Do not ask about the format first, then ask about the script after receiving the answer. When the script is already finalized, only ask about the video format in this round. Do not start writing the script draft or searching/downloading assets until you receive the user's answers in this round.
These five are independent dimensions; each must be asked as a separate question. Never combine them into combined options to meet the tool's question limit. For example, do not ask "What video format and target duration will be used for this episode?" with options like "Vertical Info-Style · 90 Seconds" — this forces two independent variables together, leaving the user unable to choose "Vertical Info-Style + 60 Seconds" except by typing it manually. Similarly, do not combine audience and style/tone into one question.
If the component you are using cannot fit five questions, present multiple components in the same response in batches. Keep each question as it is; do not split the questions across rounds or merge them to reduce the number of questions.
Do not provide bare options only. A label like "Horizontal Video" is unclear to users unfamiliar with the terminology. Add a short explanation after each option with an em dash, explaining what it looks like and where it is suitable for posting, e.g., "Horizontal Video — 16:9 full screen, suitable for Bilibili, YouTube, and viewing on computers". Keep the explanation within 20 Chinese characters (or equivalent in English) in one sentence; if the component only accepts short labels and cannot fit the explanation, write these sentences in the main text before the component.
Question Template for the Kickoff Round
Follow this structure to create five questions, each with a free-text input option. The example below uses the topic of DeepSeek's price increase; rewrite the options according to the current topic, the options for Question 5 must be rewritten, do not copy them directly:
What video format will be used for this episode? (Single selection) — Use the three options as written in the "Mandatory Question: Video Format" section below, do not create a new set here
What is the target duration? (Single selection)
90 seconds (Recommended) — Approximately 540 words, enough to fully explain the price increase and reasons
60 seconds — Approximately 360 words, only core judgments are retained
30 seconds — Approximately 180 words, highlighting a single explosive point
Who is the main audience? (Single selection)
General tech and business users (Recommended) — Focus on price changes and business logic
AI developers — Focus on API costs and model selection
General users — Focus on explaining whether it affects their daily use
What style/tone is preferred? (Single selection)
Strong hook commentary (Recommended) — Clear opinions, start with conflict
Practical interpretation — Focus on specific impacts on readers and countermeasures
Which information points must be covered? (Multiple selections)
Specific figures: price increase rate, time period, latest price
Whether general users are affected
Why this decision is made now
Real impact on practitioners' costs
Whether it is still cost-effective after the price increase
I have no special requirements, please decide for me
The last option for Question 5 must be "I have no special requirements, please decide for me". The options for this question are created based on the current topic; the user may not have specific ideas about which points to cover, so provide an exit for one-click authorization instead of forcing them to select from a list of acceptable points. Do not add this option to the first four questions: the format, duration, audience, and tone all have clear recommended options; if the user does not select, the fallback will be used, so there will be no blockage.
If the user selects this option, it means they explicitly said "You decide the mandatory information points": select the points you need according to the script requirements, then clearly state in your response which points you decided on. If the user selects this option along with other specific points, follow the specific points and ignore this option. Authorization is only for this item; do not decide the other four items on behalf of the user.
How to Deliver the Questions to the User
Always use an interactive question component that presents the questions along with options and waits for the user's selection. Do not start with plain text. Judge by capability, not name: different products have different names (e.g.,
ask
,
ask_question
,
AskUserQuestion
,
ask_user_input
,
request_user_input
,
requestUserInput
, etc.); use the one with the correct function.
When you are ChatGPT, use
ask_user_input
. It is a GenUI message component written in the response body, not a registered tool — this is a different capability path, do not confuse them:
It will not appear in
ALL_TOOLS
, tool search results, or the MCP tool list. Not finding it in the tool list is not evidence that it is unavailable.
Do not judge whether it can be used by searching for the tool name; directly output this component in the response body.
Do not call
request_user_input
in Default/Work mode: it is only available in Plan mode, and calling it here will definitely return
request_user_input is unavailable in Default mode
, which is a useless error path. Only use it if you confirm you are in Plan mode; if you are unsure, directly output the GenUI component.
Each question in the component must include
question
,
options
(2 to 10 short options),
type
(
single_select
or
multi_select
), and
free_text_placeholder
. Put all five dimensions into the same
questions
array and ask them in one component; the "maximum 3 questions" mentioned elsewhere is a recommendation, not a hard limit for this component. Tests show that putting 5 independent questions in one component renders normally, and all 5 answers are returned correctly.
End the round immediately after outputting the component; do not continue writing text after the component, let alone start working.
Prohibited Assertion: Do not tell the user things like "
ask_user_input
is not currently available", "No GenUI capability", "Only plain text questions can be used" until you have actually output the GenUI component and received a rendering failure result. Asserting unavailability without trying is the most common mistake in this step.
Only when the host explicitly returns that GenUI is not supported, or the component indeed fails to render, is it allowed to downgrade in the following order:
Put two components in the same response, containing 3 questions and 2 questions respectively.
If two components also fail to render, switch to numbered plain text options and tell the user they can reply with all answers at once like "1A 2A 3A 4A 5ABC".
Under no circumstances should you skip the questions or use default values on your own due to component rendering failure.
Other Products: Find the corresponding tool or component writing method according to the capability standard above; if one path is rejected, switch to another. Only after all attempts fail to bring up the option box should you revert to numbered plain text options and wait for the user's reply.
Under no circumstances should you skip the questions or make decisions on your own due to poor question mechanism. Failure to ask is a form issue, not a reason to make decisions independently.
Mandatory Question: Video Format
Even if the narration script is finalized, this item must be asked once; when the script is not finalized, ask it in the same round as the items under "When the Script Is Not Finalized":
Vertical Info-Style (Default): The finished video is 9:16, with content rendered in 16:9 horizontal format embedded in the middle of the canvas, hook headline at the top, and subtitles + IP character at the bottom
Vertical Video: Content fills the 9:16 canvas
Horizontal Video: Content fills the 16:9 canvas
The above three points are for your own understanding of the formats. When asking, include the differences and applicable scenarios in the options; do not directly present the canvas parameters to the user. Write them like this:
Vertical Info-Style (Recommended) — 9:16 canvas with 16:9 video embedded in the middle, large headline at the top, highest information density
Vertical Video — 9:16 full screen, suitable for Douyin, WeChat Channels, Xiaohongshu
Horizontal Video — 16:9 full screen, suitable for Bilibili, YouTube, and viewing on computers
If the user does not answer or asks you to decide, use the Vertical Info-Style and clearly state in your response "Video format defaults to Vertical Info-Style".
The format is not a field you need to submit; it is selected by the user on Niwo's rendering interface. Writing it into
content.json
will directly cause validation failure. You ask this only for two purposes:
Determine whether to write a hook headline: Only the Vertical Info-Style has this layout space.
Therefore, once the format is confirmed, the way to write the hook headline is fixed; they cannot be written independently:
If the user selects Vertical Info-Style:
content.json
must include
hook_headline
. Without it, the top headline bar will have no content, leaving a blank area at the start of the video, and Niwo will not automatically fill it with the title or script. It must be written and confirmed with the user along with the narration script; see Step 1 for details.
If the user selects Vertical Video or Horizontal Video: Do not write
hook_headline
. These formats do not have this layout space, so it will not appear on the screen; more importantly, Niwo will treat the bundle as "prepared for Info-Style" and directly set the default format on the rendering interface to Vertical Info-Style, conflicting with the user's selected format.
If the user does not answer the format and you default to Vertical Info-Style:
hook_headline
must be written according to the Info-Style rules and confirmed with the user along with the script; at the same time, clearly state in your response that the default format was used.
After confirmation, leave a note in
notes
, e.g., "Assets collected in horizontal composition, recommend selecting Vertical Info-Style on Niwo", to remind the user to select the same format on the interface. If the selection is reversed, the video will be cropped to fill the screen, and the subject may be easily cut off.
When the Script Is Not Finalized, Ask These in the Same Round as the Format
When the script is not finalized, ask the following four items in the same round as the video format; do not start a new round:
Approximate target duration (see "Duration vs. Word Count" below for word count conversion)
Who the content is for
What style/tone to use
Which information points must be covered
Do not start writing the script draft or searching/downloading assets until you receive the user's answers in this round. After receiving the answers, provide a script draft; for Vertical Info-Style, include the hook headline along with the script. Only proceed to find assets after the user revises it and explicitly says "This version is final".
Step 1: Confirm the Narration Script
The
script
in
content.json
is a finalized narration script: it will be read word-for-word as voiceover and displayed word-for-word as subtitles; Niwo will not rewrite, polish, add, or delete any words. Therefore, finalize the script before starting to find assets.
If there is already a finalized script confirmed by the user in the conversation, use it directly.
If it is not finalized, do not make decisions on your own. The round in Step Zero has already asked about duration, audience, style, and mandatory information points. Write a draft according to the user's answers, and only proceed after the user revises it and explicitly says "This version is final".
How to write the script and what style is better should follow the conclusions from your conversation with the user; this skill does not make decisions for you.
When the format selected in Step Zero is Vertical Info-Style, the hook headline and narration script are two parts of the same content and must go through this process together: include the hook headline in the draft, present it to the user along with the script, and only consider it finalized after the user revises it and explicitly says "This version is final". Do not finalize the script and then go find assets, leaving the hook headline to be added later when writing
content.json
— that headline is the largest text in the opening seconds, and it is not finalized until the user approves it.
Even if the user directly provides a finalized narration script, the hook headline must still be extracted separately and confirmed with the user, as a finalized script does not mean a finalized headline.
The only hard requirement: the final
script
must be a finished text that can be read word-for-word directly, without titles, section subheadings, shot descriptions, emojis, or stage directions in parentheses.
Duration vs. Word Count
The finished video duration is entirely determined by the actual length of the voiceover reading the
script
; there are no other controls: Niwo will not add or delete words to meet the duration, nor will it stretch or compress the footage to align with the target seconds. Therefore, the number of words written determines the length of the video.
The original speed of Chinese voiceover is approximately 6 words per second; convert the target duration according to this rate:
30 seconds ≈ 180 words
1 minute ≈ 360 to 380 words
1.5 minutes ≈ 540 words
Pronunciation of Polyphonic Characters
After finalizing the script, scan for polyphonic characters and write those that the voiceover is likely to mispronounce into
pronunciations
in
content.json
. For example, the character "调" in "调用量" (diàoyòngliàng) should be pronounced diào, but the voiceover will default to tiáo. See
references/content-schema.md
for writing methods.
Only mark the character that is actually likely to be mispronounced; the fewer marks, the more natural the voiceover tone, and the more accurate the subtitle timestamps. Do not add phonetic notation to the entire sentence.
Hook Headline
Mandatory for Vertical Info-Style, omitted for the other two formats. The top headline bar includes this hook headline, extracted from the narration script and written into
hook_headline
in
content.json
. It is not included in the voiceover or subtitles; it only serves to grab attention at the opening.
Recommended to be 2 lines: the first line sets the scene, the second line presents the result or conflict.
Each line should not exceed 12 Chinese characters; enclose the most impactful number or conclusion in
[[ ]]
for highlighting. English words and numbers take up half a character width; a line like "DeepSeek砸1.4亿" (DeepSeek invests 140 million) is equivalent to 8.2 characters and does not exceed the limit. Exceeding 12 characters will trigger a warning, and exceeding 14 will cause validation failure.
Confirm it with the user along with the script; do not make decisions on your own. Provide 1 to 2 candidates for the user to choose or revise, and only proceed after the user approves.
The other two formats do not have this layout space; writing it will not appear on the screen, and will also set the default format on Niwo's rendering interface to Vertical Info-Style, conflicting with the user's selected format. Therefore, omit this field entirely.
After finalizing the script, write the names of public references used into
sources
in
content.json
. It is not included in the voiceover or subtitles; it is only rendered as small text at the bottom of the screen.
Write it by default, do not ask the user if they want it. You know best which references you checked when writing the script; whether to display it is a toggle on the user's rendering interface, not something you decide on their behalf.
Write it if there are references; omit this field if there are none, do not fabricate sources to fill the field.
Only write the source name (e.g., announcement name, media report name), do not write URLs; each entry should not exceed 24 Chinese characters in width.
Do not add the prefix "Source:"; that will be added by Niwo.
Disclaimer is a separate matter: its toggle and content are in the user's rendering parameters, independent of
sources
; do not write it into
content.json
.
Example:
json
"sources":["Unitree Robotics Prospectus","DeepSeek Official Announcement","Sina Finance"]
See the
sources
section in
references/content-schema.md
for writing methods and validation rules.
Step 2: Collect Assets
Two types of assets are needed.
B-Roll Video Footage
Search and download real videos directly from the web, public asset websites, or related web pages. These can include people, scenes, product operations, platform usage, industry footage, news scenes, and live-action shots corresponding to abstract concepts.
Web Image Assets
Use image search engines like Bing or Baidu to find real web images directly related to the script content. Prioritize collecting:
Images of related products, companies, and people
Screenshots of real app interfaces and historical versions
News report illustrations
Industry reports and data charts
Product comparison charts
Images of activities, events, and historical materials
Logos, promotional images, and media materials
Web photos or illustrations that accurately express the concepts in the script
Assets to Explicitly Avoid
No original motion effects
No concept animations rendered with front-end frameworks
No frame-extracted images from B-roll videos used as image assets
No low-information placeholder images instead of real materials
No large amounts of assets weakly related to the script collected just to meet the quantity
The assets you submit are the entire source of footage for the finished video: after importing the asset bundle, Niwo will not search for images online or fill in empty shots. Therefore, the assets must cover the entire script; do not leave any section without matching footage. At the same time, do not stuff weakly related assets just to meet the quantity; it is better to have fewer high-quality assets than many irrelevant ones — if there is no matching footage, it will degrade to a text-only card, which is better than mismatched footage.
For a 1 to 1.5-minute video, usually 20 to 30 images plus 8 to 10 video clips are sufficient. You decide the source channels and actual quantity. When there are far more assets than this amount, Niwo will extract them evenly according to the manifest order, so the manifest order should preferably follow the script's progression.
Try to align the asset orientation with the video format confirmed in Step Zero:
Videos: If the orientation does not match, the finished video will be cropped to fill the screen (
cover
), and the subject may be easily cut off if it is near the edge. Prioritize vertical videos for vertical finished videos, and horizontal videos for horizontal finished videos.
Images: All are displayed in full without cropping; if the orientation does not match, only blurred padding will be added above/below or left/right, so mixing vertical and horizontal images is not a major issue.
Step 3: Determine Which Seconds of Each Video to Use
Each shot in the finished video only uses a few seconds, so do not just submit a raw video of tens of seconds. Choose one of the two methods:
Trim it yourself (Recommended): Submit the trimmed short clips directly; one file is one shot, 8 to 12 seconds is most suitable. It is better to make it a bit longer: the shot duration is determined by the voiceover, which can be up to 9 seconds. If the clip is shorter than the shot, it will only be slowed down to fill the duration; if it is too short, the footage will obviously become sluggish.
to confirm the duration. Do not select segments with black screens, opening logos, or blurry transition frames; choose a segment with stable footage and clear subject.
Avoid this pitfall: if you submit a long raw video, write
summary
and
tags
in the manifest but do not write the segment time, Niwo will assume you have already selected it and start from the 0th second — which will likely capture the opening logo. Either trim it, write the segment time, or do not write
summary
and
tags
at all, letting Niwo select the shot automatically.
Do not worry about audio tracks or encoding: Niwo will re-encode all videos into silent H.264 mp4, and the finished video will use its own voiceover and BGM. The file can be in common formats like mp4 / mov / mkv / webm; it does not matter if it has original audio or not.
Step 4: Write manifest.json
Read
references/manifest-schema.md
and write according to the field descriptions inside.
Key points:
summary
is a single line of Chinese, only describing what is visible in the footage;
tags
are 2 to 5 short Chinese labels; do not write
clip_start_seconds
/
clip_end_seconds
for trimmed videos.
Step 5: Write content.json
Read
references/content-schema.md
and write according to the template inside.
Only include these fields:
schema_version
,
title
,
script
,
hook_headline
,
sources
,
pronunciations
, and
notes
:
schema_version
must be filled with
1
, which is a required protocol version number; omitting it will directly cause validation failure. All other fields are content. No other fields are accepted; writing rendering parameters (including video format) into it will also cause validation failure.
Before writing, double-check the format confirmed in Step Zero: Vertical Info-Style must include the user-confirmed
hook_headline
, while Vertical Video and Horizontal Video must not have this field. The validation script does not know which format the user selected, so it cannot detect this mismatch; you must check it yourself.
Step 6: Self-Check and Package
Run the self-check before packaging; it will check fields, file correspondence, and video segment windows. The script is in the
scripts/
directory of this skill; call it with the absolute path:
Fix any errors until it passes; do not package with errors. If you only have a copied prompt and do not have this script, manually check each item according to the self-check list at the end. After passing the validation:
Do not include soft links in the zip, nor any other files outside the above structure.
Delivery
Deliver the zip file to the user and tell them to upload it to Niwo to generate the video:
<!-- TODO: Replace with official upload entry address and product name -->
Before uploading, the user can re-screen the assets: delete unsatisfactory files directly, or add new ones directly to
images/
or
videos/
— extra files not written in the manifest can also be used, and Niwo will automatically add descriptions.
Pre-Delivery Self-Check
Before starting, all questions about video format and script requirements were asked in one go, and the answers came from the user's current response, not inferred from memory or historical preferences; any fallback default values used were clearly stated in the response
scripts/validate_bundle.py
ran successfully with no errors
Both
content.json
and
manifest.json
have
"schema_version": 1
written
Asset orientation matches the video format confirmed in Step Zero, and a note in
notes
reminds the user to select the same format on Niwo
script
is the finalized narration confirmed by the user, readable word-for-word, with no titles or stage directions
hook_headline
exists and is confirmed by the user when the format is Vertical Info-Style; this field is omitted when the format is Vertical Video or Horizontal Video
Each asset has an entry in
manifest.json
, and the
file
path corresponds to the actual file one-to-one
Each video is either trimmed into a short shot of a few seconds, or the segment time is marked in the manifest
All
summary
are single-line Chinese, describing the footage rather than its meaning
All assets are closely related to the script, with no placeholder images, frame-extracted images, or rendered animations
content.json
contains no rendering parameters, only content
hook_headline
(if present) has 1 to 3 lines, each within 12 Chinese characters (English/numbers count as half a character), with at least one
[[ ]]
highlight
sources
is written by default when public references are used in the script, only including source names, no "Source:" prefix, and no disclaimer