Blog URL to Video with AI Voice Over

This example demonstrates how to create a video from a blog post URL with AI-generated voice-over narration. The API will extract the content from the blog and generate a video with both relevant visuals and professional narration.

Overview

This example covers:

  • Getting an access token
  • Creating a video from a blog URL with AI voice-over
  • Using the "Brian" AI voice speaker for narration
  • Automatic content extraction and scene generation
  • Monitoring job status and retrieving the final video

Node.js Example

Prerequisites

npm install axios

Complete 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";

// Blog URL to convert to video
const BLOG_URL = "https://pictory.ai/blog/edutainment-combining-fun-and-learning-for-effective-education";

async function createBlogToVideoWithVoiceOver() {
  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 from Blog URL with AI Voice Over
    console.log("Step 2: Creating video from blog URL with AI voice-over...");
    const storyboardResponse = await axios.post(
      `${API_BASE_URL}/v2/video/storyboard/render`,
      {
        videoName: "blog_to_video_with_voice",
        voiceOver: {
          enabled: true,
          aiVoices: [
            {
              speaker: "Brian",
            },
          ],
        },
        scenes: [
          {
            blogUrl: BLOG_URL,
            createSceneOnNewLine: true,
            createSceneOnEndOfSentence: true,
          },
        ],
      },
      {
        headers: {
          "Content-Type": "application/json",
          Authorization: accessToken,
        },
      }
    );

    const renderJobId = storyboardResponse.data.data.jobId;
    console.log("Blog to video with voice-over 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 from blog with AI voice-over 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
createBlogToVideoWithVoiceOver();

Python Example

Prerequisites

pip install requests

Complete 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'

# Blog URL to convert to video
BLOG_URL = "https://pictory.ai/blog/edutainment-combining-fun-and-learning-for-effective-education"

def create_blog_to_video_with_voiceover():
    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 from Blog URL with AI Voice Over
        print('Step 2: Creating video from blog URL with AI voice-over...')
        storyboard_response = requests.post(
            f'{API_BASE_URL}/v2/video/storyboard/render',
            json={
                'videoName': 'blog_to_video_with_voice',
                'voiceOver': {
                    'enabled': True,
                    'aiVoices': [
                        {
                            'speaker': 'Brian'
                        }
                    ]
                },
                'scenes': [
                    {
                        'blogUrl': BLOG_URL,
                        'createSceneOnNewLine': True,
                        'createSceneOnEndOfSentence': True
                    }
                ]
            },
            headers={
                'Content-Type': 'application/json',
                'Authorization': access_token
            }
        )
        storyboard_response.raise_for_status()

        render_job_id = storyboard_response.json()['data']['jobId']
        print('Blog to video with voice-over 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 from blog with AI voice-over 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_blog_to_video_with_voiceover()

Key Parameters

  • blogUrl: The full URL of the blog post to convert
  • voiceOver: Configuration for AI voice-over narration
    • enabled: Set to true to enable voice-over
    • aiVoices: Array of AI voice configurations
      • speaker: The name of the AI voice (e.g., "Brian")

How It Works

  1. The API fetches the content from the provided blog URL
  2. It extracts the main article text
  3. The extracted text is processed and split into scenes
  4. AI voice-over is generated for each scene's text
  5. Relevant visuals are automatically selected
  6. Voice-over is synchronized with the visuals
  7. A complete video with narration is generated

Use Cases

  • Create narrated video summaries of blog posts
  • Repurpose written content for audio/video platforms
  • Generate podcast-style videos from articles
  • Make blog content more accessible to audio learners
  • Automate video content creation for social media

Response

The API returns a job ID for monitoring the video creation progress. Once completed, you'll receive a video URL containing the visual representation of your blog post with AI-generated narration.

Notes

  • Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your actual API credentials
  • The blog URL must be publicly accessible
  • The AI voice-over is automatically synchronized with the video scenes
  • Processing time depends on the length of the blog post
  • You can customize voice speed and amplification if needed