Podcast to Video (Audio URL to Video)

This example demonstrates how to create a video from an audio file URL (podcast or any audio content). The API will transcribe the audio and generate a video with synchronized visuals and subtitles.

Overview

This example covers:

  • Getting an access token
  • Creating a video from an audio URL
  • Specifying the audio language for transcription
  • Automatic visual selection based on audio content
  • 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";

// Audio URL to convert to video (podcast or audio file)
const AUDIO_URL =
  "https://audios-prod.pictorycontent.com/polly/production/projects/6pacgpeerj6kglqu0ueh4e40vg/72fb25df0e5b4d1b880a86d036bdb715.mp3";

async function createPodcastToVideo() {
  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 Audio URL
    console.log("Step 2: Creating video from audio URL...");
    const storyboardResponse = await axios.post(
      `${API_BASE_URL}/v2/video/storyboard/render`,
      {
        videoName: "podcast_to_video",
        scenes: [
          {
            audioUrl: AUDIO_URL,
            audioLanguage: "en-US",
          },
        ],
      },
      {
        headers: {
          "Content-Type": "application/json",
          Authorization: accessToken,
        },
      }
    );

    const renderJobId = storyboardResponse.data.data.jobId;
    console.log("Podcast to video 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 podcast 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
createPodcastToVideo();

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'

# Audio URL to convert to video (podcast or audio file)
AUDIO_URL = "https://audios-prod.pictorycontent.com/polly/production/projects/6pacgpeerj6kglqu0ueh4e40vg/72fb25df0e5b4d1b880a86d036bdb715.mp3"

def create_podcast_to_video():
    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 Audio URL
        print('Step 2: Creating video from audio URL...')
        storyboard_response = requests.post(
            f'{API_BASE_URL}/v2/video/storyboard/render',
            json={
                'videoName': 'podcast_to_video',
                'scenes': [
                    {
                        'audioUrl': AUDIO_URL,
                        'audioLanguage': 'en-US'
                    }
                ]
            },
            headers={
                'Content-Type': 'application/json',
                'Authorization': access_token
            }
        )
        storyboard_response.raise_for_status()

        render_job_id = storyboard_response.json()['data']['jobId']
        print('Podcast to video 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 podcast 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_podcast_to_video()

Key Parameters

  • audioUrl: The full URL of the audio file to convert (max 3000 characters, must be a valid URI)
  • audioLanguage: The language of the audio content (required when using audioUrl)

Supported Audio Languages

  • en-US - English (US)
  • en-AU - English (Australian)
  • en-GB - English (British)
  • en-IN - English (Indian)
  • en-IE - English (Irish)
  • fr-CA - French (Canadian)
  • fr-FR - French (France)
  • de-CH - German (Swiss)
  • de-DE - German (Germany)
  • it-IT - Italian
  • es-ES - Spanish (Spain)
  • es-US - Spanish (US)
  • nl-NL - Dutch
  • pt-BR - Portuguese (Brazilian)
  • ja-JP - Japanese
  • ko-KR - Korean
  • ru-RU - Russian
  • hi-IN - Hindi
  • ta-IN - Tamil

How It Works

  1. The API fetches the audio file from the provided URL
  2. The audio is transcribed using speech-to-text technology
  3. The transcribed text is processed and split into scenes
  4. Relevant visuals are automatically selected based on the content
  5. Subtitles are generated from the transcription
  6. The original audio is synchronized with visuals and subtitles
  7. A complete video is generated

Use Cases

  • Convert podcasts to video format for YouTube or social media
  • Add visuals to audio content automatically
  • Create video versions of audio interviews or discussions
  • Repurpose audio content for video platforms
  • Generate subtitled videos from audio recordings
  • Make audio content more engaging with synchronized visuals

Response

The API returns a job ID for monitoring the video creation progress. Once completed, you'll receive a video URL containing your audio with synchronized visuals and subtitles.

Notes

  • Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your actual API credentials
  • The audio file must be accessible via a public URL
  • Supported audio formats include MP3, WAV, and other common formats
  • The audioLanguage parameter is required for accurate transcription
  • Processing time depends on the length of the audio file
  • The original audio is preserved in the final video