Text to Video with Intro Video and Outro Video
This example demonstrates how to create a video with an intro video scene and an outro video scene. This is perfect for adding branded video intros and outros to your videos.
Overview
This example covers:
- Getting an access token
- Adding an intro scene with video background
- Adding an outro scene with video background
- Understanding optional minimum durations for intro/outro scenes
- Understanding how video duration is determined automatically
- Understanding background-only scenes
- Monitoring job status and retrieving the final video
Node.js Example
Prerequisites
npm install axiosComplete Code
import axios from "axios";
const API_BASE_URL = "https://api.pictory.ai/pictoryapis";
const CLIENT_ID = "YOUR_CLIENT_ID";
const CLIENT_SECRET = "YOUR_CLIENT_SECRET";
const STORY_TEXT =
"AI is poised to significantly impact educators and course creators on social media. By automating tasks like content generation, visual design, and video editing, AI will save time and enhance consistency.";
const INTRO_VIDEO_URL = "https://pictory-static.pictorycontent.com/PictoryLogoINTRO.mp4";
const OUTRO_VIDEO_URL = "https://pictory-static.pictorycontent.com/PictoryLogoOUTRO.mp4";
async function createTextToVideoWithIntroOutro() {
try {
// Step 1: Get Access Token
console.log("Step 1: Getting access token...");
const tokenResponse = await axios.post(
`${API_BASE_URL}/v1/oauth2/token`,
{
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
},
{
headers: {
"Content-Type": "application/json",
},
}
);
const accessToken = tokenResponse.data.access_token;
console.log("Access token obtained successfully");
console.log("Token expires in:", tokenResponse.data.expires_in, "seconds\n");
// Step 2: Create Video with Intro Video and Outro Video
console.log("Step 2: Creating video with intro and outro...");
const storyboardResponse = await axios.post(
`${API_BASE_URL}/v2/video/storyboard/render`,
{
videoName: "text_to_video_intro_outro",
scenes: [
// Intro scene with video background
{
background: {
type: "video",
visualUrl: INTRO_VIDEO_URL,
},
minimumDuration: 2, // Optional: 2 seconds intro
},
// Main content scene
{
story: STORY_TEXT,
createSceneOnNewLine: true,
createSceneOnEndOfSentence: true,
},
// Outro scene with video background
{
background: {
type: "video",
visualUrl: OUTRO_VIDEO_URL,
},
// minimumDuration not specified - will use the actual video duration
},
],
},
{
headers: {
"Content-Type": "application/json",
Authorization: accessToken,
},
}
);
const renderJobId = storyboardResponse.data.data.jobId;
console.log("Video with intro and outro render job created");
console.log("Job ID:", renderJobId, "\n");
// Step 3: Monitor Job Status
console.log("Step 3: Monitoring job status...");
let jobCompleted = false;
let jobResult = null;
while (!jobCompleted) {
const jobStatusResponse = await axios.get(`${API_BASE_URL}/v1/jobs/${renderJobId}`, {
headers: {
Authorization: accessToken,
},
});
const status = jobStatusResponse.data.data.status;
console.log("Current status:", status);
if (status === "completed") {
jobCompleted = true;
jobResult = jobStatusResponse.data;
console.log("\nVideo with intro and outro created successfully!");
console.log("Video URL:", jobResult.data.videoURL);
} else if (status === "failed") {
throw new Error("Job failed: " + JSON.stringify(jobStatusResponse.data));
} else {
// Wait 5 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
return jobResult;
} catch (error) {
console.error("Error:", error.response?.data || error.message);
throw error;
}
}
// Run the function
createTextToVideoWithIntroOutro();Python Example
Prerequisites
pip install requestsComplete Code
import requests
import time
import json
API_BASE_URL = 'https://api.pictory.ai/pictoryapis'
CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
STORY_TEXT = "AI is poised to significantly impact educators and course creators on social media. By automating tasks like content generation, visual design, and video editing, AI will save time and enhance consistency."
INTRO_VIDEO_URL = "https://pictory-static.pictorycontent.com/PictoryLogoINTRO.mp4"
OUTRO_VIDEO_URL = "https://pictory-static.pictorycontent.com/PictoryLogoOUTRO.mp4"
def create_text_to_video_with_intro_outro():
try:
# Step 1: Get Access Token
print('Step 1: Getting access token...')
token_response = requests.post(
f'{API_BASE_URL}/v1/oauth2/token',
json={
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
},
headers={
'Content-Type': 'application/json'
}
)
token_response.raise_for_status()
access_token = token_response.json()['access_token']
print('Access token obtained successfully')
print(f"Token expires in: {token_response.json()['expires_in']} seconds\n")
# Step 2: Create Video with Intro Video and Outro Video
print('Step 2: Creating video with intro and outro...')
storyboard_response = requests.post(
f'{API_BASE_URL}/v2/video/storyboard/render',
json={
'videoName': 'text_to_video_intro_outro',
'scenes': [
# Intro scene with video background
{
'background': {
'type': 'video',
'visualUrl': INTRO_VIDEO_URL
},
'minimumDuration': 2 # Optional: 2 seconds intro
},
# Main content scene
{
'story': STORY_TEXT,
'createSceneOnNewLine': True,
'createSceneOnEndOfSentence': True
},
# Outro scene with video background
{
'background': {
'type': 'video',
'visualUrl': OUTRO_VIDEO_URL
}
# minimumDuration not specified - will use the actual video duration
}
]
},
headers={
'Content-Type': 'application/json',
'Authorization': access_token
}
)
storyboard_response.raise_for_status()
render_job_id = storyboard_response.json()['data']['jobId']
print('Video with intro and outro render job created')
print(f'Job ID: {render_job_id}\n')
# Step 3: Monitor Job Status
print('Step 3: Monitoring job status...')
job_completed = False
job_result = None
while not job_completed:
job_status_response = requests.get(
f'{API_BASE_URL}/v1/jobs/{render_job_id}',
headers={
'Authorization': access_token
}
)
job_status_response.raise_for_status()
status = job_status_response.json()['data']['status']
print(f'Current status: {status}')
if status == 'completed':
job_completed = True
job_result = job_status_response.json()
print('\nVideo with intro and outro created successfully!')
print(f"Video URL: {job_result['data']['videoURL']}")
elif status == 'failed':
raise Exception(f"Job failed: {json.dumps(job_status_response.json())}")
else:
# Wait 5 seconds before checking again
time.sleep(5)
return job_result
except requests.exceptions.RequestException as error:
print(f'Error: {error}')
if hasattr(error, 'response') and error.response is not None:
print(f'Response: {error.response.text}')
raise
# Run the function
if __name__ == '__main__':
create_text_to_video_with_intro_outro()Key Parameters
Background Object
- background.type: Type of background
"video"- For video backgrounds (both intros and outros)
- background.visualUrl: URL to the background video file
Minimum Duration
- minimumDuration: Optional duration in seconds for background-only scenes
- Optional - If not provided, the system will automatically determine the duration from the video file at runtime
- When specified, ensures intro/outro scenes play for a specific time
- If the video is shorter than minimumDuration, it may loop depending on the loop settings
- If the video is longer, it will be trimmed to minimumDuration
- If omitted, the full duration of the provided video will be used
Scene Structure
Background-Only Scene (Intro/Outro)
A scene with only a background (no story text) requires:
- A
backgroundobject withtypeandvisualUrl - Optionally, a
minimumDurationto specify how long the scene should display- If
minimumDurationis not provided, the system will automatically use the actual duration of the video file - If
minimumDurationis provided, the video will be trimmed or looped to match that duration
- If
Regular Content Scene
A scene with story text:
- Has a
storyfield with text content - Duration is calculated based on text length and voice-over
- Can optionally have a background as well
Use Cases
Intro Video Scenes
- Animated company logo
- Channel branding with motion graphics
- Title animations
- Episode intros with movement
- Series branding with video effects
Outro Video Scenes
- Animated subscribe/follow calls-to-action
- Social media links with animations
- Next episode teasers with clips
- Animated credits
- Thank you animations
Advanced Examples
Intro with Text Overlay
{
background: {
type: "video",
visualUrl: "https://pictory-static.pictorycontent.com/PictoryLogoINTRO.mp4"
},
story: "Welcome to our channel",
minimumDuration: 3 // Optional: override video duration
}Intro without minimumDuration (Auto-detect)
{
background: {
type: "video",
visualUrl: "https://pictory-static.pictorycontent.com/PictoryLogoINTRO.mp4"
}
// minimumDuration omitted - will use the actual video duration
}Multiple Outros
scenes: [
{ story: "Main content..." },
{
background: {
type: "video",
visualUrl: "https://pictory-static.pictorycontent.com/PictoryLogoOUTRO.mp4",
},
// No minimumDuration - uses actual video duration
},
{
background: {
type: "image",
visualUrl: "https://example.com/thankyou.png",
},
minimumDuration: 3, // Required for images
},
];Video Background Settings
You can control video background behavior:
background: {
type: "video",
visualUrl: OUTRO_VIDEO_URL,
settings: {
mute: true, // Mute the outro video audio
loop: false // Don't loop the video
}
}Best Practices
- Intro Duration: Keep intros short (2-5 seconds) to maintain viewer engagement
- Outro Duration: Outros can be longer (5-10 seconds) for calls-to-action
- Video Format: Use MP4 format for best compatibility
- Video Resolution: Use high-resolution videos (1920x1080)
- Auto-Duration: For custom video URLs, omit
minimumDurationto use the actual video length automatically - Video Length: If using
minimumDuration, ensure video files are close to that duration to avoid excessive looping or trimming - Audio: Consider muting background videos if you have voice-over or music
- Branding: Use consistent intro/outro videos across your video series
Common Intro/Outro Durations
- Quick Intro: 2-3 seconds
- Standard Intro: 4-5 seconds
- Detailed Intro: 6-8 seconds
- Short Outro: 3-5 seconds
- Standard Outro: 5-8 seconds
- Long Outro: 10-15 seconds
Response
The API returns a job ID for monitoring the video creation progress. Once completed, you'll receive a video URL with intro and outro video scenes included.
Notes
- Replace
YOUR_CLIENT_IDandYOUR_CLIENT_SECRETwith your actual API credentials - Video files must be accessible via public URLs
- minimumDuration is optional - If not provided, the system automatically detects the video duration at runtime for custom video URLs (non-stock library videos)
- When minimumDuration is specified, it ensures scenes play for at least the specified time
- If the background video is shorter than minimumDuration, it may loop (unless loop is set to false)
- If the background video is longer than minimumDuration, it will be trimmed
- For image backgrounds, minimumDuration is required as images don't have inherent duration
- You can add background music to intro/outro scenes
- You can add voice-over to intro/outro scenes by including a
storyfield - Both intro and outro videos will be processed and included in the final rendered video
Duration Behavior Summary
| Scenario | minimumDuration | Behavior |
|---|---|---|
| Custom video URL | Not provided | Uses actual video duration (auto-detected at runtime) |
| Custom video URL | Provided (e.g., 5s) | Video is trimmed or looped to match 5 seconds |
| Stock library video | Provided | Video is trimmed or looped to match specified duration |
| Image background | Required | Must specify duration as images have no inherent duration |
Updated about 2 hours ago
