Integration by Closed Caption Creator

Seamless Caption Editing, Anywhere.

Embed our powerful subtitle editor

Give your users professional-grade caption editing without building it yourself. Our new IFrame Embed support lets you integrate our intuitive caption editor into your platform with minimal effort. Your users can edit, review, and correct captions without ever leaving your ecosystem, while you save valuable development time and resources.

🎬 Watch Free CourseView Documentation

Browser-based Subtitle Editor

Subtitle Editor, Ready for Your Platform.

Embed our editor on your website using an IFrame tag and a couple lines of code.

Embedding our caption editor is remarkably simple—just a few lines of code to get started. With support for over 30 different closed caption formats, we seamlessly integrate with virtually any captioning workflow. Whether you're handling standard SRT files or specialized broadcast formats, our editor has you covered.

Designed specifically for broadcast manufacturers and video platforms, our embedded editor fills the critical gap for services that support video captioning but lack editing capabilities. We're committed to your success with free technical support and training throughout the development process, ensuring a smooth implementation that meets your specific needs.

  • Easy to setup and configure
  • No backend required
  • Import and publish captions
  • Import multiple subtitle tracks and languages
  • Media support for HLS streams,  cloud storage, YouTube URL, Vimeo links, and more
  • Theming options for seamless brand integration
  • Flexible pricing options
Read Documentation  Watch Course
ElevenLabs Display Photo showing a female robot and the text "Eleven Labs AI Voice Generator & Best Text to Speech"

Have Questions?

Contact our team for a free demo.

Book a Demo

Developer Docs

IFrame Remote Documentation

Build your own integration with Closed Caption Creator using our IFrame Remote.

Leverage Closed Caption Creator's incredible flexibility for all your captioning and timed-text metadata needs. This section provides the essential reference documentation—including setup guides, API details, and practical examples—to get your integration up and running fast.

Introduction

Overview

The Closed Caption Creator IFrame Remote provides a powerful, embeddable subtitle and timed-text editor designed to seamlessly integrate into your web-based applications. Instead of building complex captioning functionalities from scratch, you can leverage our professional-grade editor to empower your users with advanced editing capabilities directly within your platform.

How It Works: Communication with PenPal JS

Our IFrame Remote is designed for secure and efficient cross-window communication using PenPal JS. This lightweight library facilitates reliable two-way communication between your parent application and the embedded editor, allowing you to:

  • Programmatically control the editor's behavior (e.g., load media, import captions, apply settings).
  • Receive updates and metadata including markers, captions, speakers, etc.

This approach ensures a robust and flexible integration, enabling you to build highly interactive and customized captioning workflows.

Getting Started Resources

To help you begin immediately, here are two essential links:

  • IFrame POC System: Use the following link as the source attribute in your IFrame tag to begin: https://iframe-demo.closedcaptioncreator.com
  • PenPal JS CDN: Include this library in your parent application to enable communication with the IFrame Remote: https://unpkg.com/penpal@^7/dist/penpal.min.js

Dive into the Getting Started section below to begin your integration.

Getting Started

This section will walk you through the fundamental steps to embed the Closed Caption Creator IFrame Remote into your web application and establish communication for controlling the editor.

Prerequisites

To follow along, you should have a basic understanding of HTML and JavaScript.

Step 1: Import Penpal JS

Import PenPal JS using NPM, or CDN.

Code Snippet
HTML Code
<!DOCTYPE html>
<html lang="en">
<head>
    ...
</head>
<body>
    ...
    <script src="https://unpkg.com/penpal@^7/dist/penpal.min.js"></script>
</body>
</html>
Step 2: Embed the IFrame

Begin by adding an element to your HTML where you want the editor to appear. Ensure it points to the Closed Caption Creator IFrame demo URL as its src (https://iframe-demo.closedcaptioncreator.com). Giving your iframe an id (e.g., editor) will make it easy to reference in JavaScript.

Code Snippet
HTML Code
<div class="iframe-container">
    <iframe id="editor" 
        src="https://iframe-demo.closedcaptioncreator.com/" 
        class="w-100 rounded" 
        style="height: 90vh;" 
        frameborder="0" 
        allow="accelerometer; autoplay; clipboard-write; encrypted-media"
        allowfullscreen>
    </iframe>
</div>
  • id="editor": Used to easily select the iframe element in JavaScript.
  • src="https://iframe-demo.closedcaptioncreator.com/": This is the URL of the Closed Caption Creator IFrame editor itself.
  • style="height: 90vh;": Sets the initial height of the iframe to take up 90% of the viewport height. Adjust this as needed for your layout.
  • allowfullscreen: Allows the user to toggle the iframe into fullscreen mode.
JavaScript Code
document.addEventListener('DOMContentLoaded', () => {
    const iframe = document.getElementById('editor');
});
Step 3: Establish Connection with PenPal

Once the IFrame is loaded, you'll establish a connection using PenPal. This connection provides a remote object that allows you to call functions exposed by the IFrame, and optionally, define methods on the parent window that the IFrame can call.

Code Snippet
JavaScript Code
document.addEventListener('DOMContentLoaded', () => {
    const iframe = document.getElementById('editor'); // Get reference to your iframe
    let iframeConnection = null; // Will store the remote object for calling iframe functions

    const connectToIframe = async () => {
        try {
            // Create a messenger to communicate with the iframe
            const messenger = new Penpal.WindowMessenger({
                remoteWindow: iframe.contentWindow,
                allowedOrigins: ['*'] // IMPORTANT: For production, restrict this to your iframe's origin!
            });

            // Connect to the iframe
            const connection = Penpal.connect({
                messenger,
                // Define methods the parent exposes to the iframe (optional)
                methods: {
                    //...
                }
            });

            // Wait for the connection to be established
            const remote = await connection.promise;
            console.log('Connected to iframe');
            iframeConnection = remote; // Store the remote object for later use

            // ... (initial editor configuration calls will go here)
            
        } catch (error) {
            console.error('Connection error:', error);
        }
    };

    // Initialize connection when iframe loads
    iframe.addEventListener('load', connectToIframe);
});
  • Penpal.WindowMessenger: Configures how PenPal will communicate. remoteWindow points to the iframe's content window. allowedOrigins: ['*'] is set for demo purposes, but you must specify the exact origin(s) of your iframe (e.g., https://iframe-demo.closedcaptioncreator.com) in a production environment for security.
  • Penpal.connect: Initiates the connection. The methods object allows you to define functions on your parent page that the IFrame can call (e.g., parentMethod, notifyParent).
  • connection.promise: This Promise resolves once the connection to the IFrame is successfully established. The resolved value (remote) is the object containing all the functions exposed by the IFrame Remote that you can call.
Step 4: Initial Editor Configuration

Once connected, you can immediately start interacting with the editor. A common first step is to configure basic project settings and load media/captions. This often involves showing a loading modal to the user.

Code Snippet
JavaScript Code
await remote.updateModalTitle("Project Import");
await remote.toggleStatusModal(true); // Show the modal regardless of its current state
await remote.updateModalStatus({ // Update modal progress and message
    progress : 5,
    msg : "Setting project settings..."
});

/* Set Project Settings (framerate, dropFrame, incode) */
await remote.setProjectName("IFrame Demo Project");
await remote.setProjectDescription("This is a demo project for iframe communication.");
await remote.setProjectFrameRate(29.97);
await remote.setProjectDropFrame(true);
await remote.setProjectIncode("00:00:00:00");

/* Step 2. Loading Subtitle File */
await remote.updateModalStatus({
    progress : 50,
    msg : "Loading Subtitles..."
});

await remote.importSubtitle(subtitleUrl, subtitleProfile);

/* Step 3. Loading Video File */
await remote.updateModalStatus({
    progress : 75,
    msg : "Loading media..."
});

await remote.importMedia(mediaUrl, "https://m.media-amazon.com/images/M/MV5BMTljNGI3NTAtYTU2ZC00ZGQzLTg2ZDAtNzQ1NDk1YzBiY2M5XkEyXkFqcGc@._V1_QL75_UX522_.jpg");

/* Audio Peak Data */
await remote.setMediaPeaksPath(audioPeaksUrl);
await remote.toggleTimeline(true);

await remote.toggleStatusModal(false); // Hide the modal
await remote.alertUser({ // Show a success alert
    title : "Project Import",
    text : "Project imported successfully!",
});
  • This sequence demonstrates calling various functions on the remote object to set up the project, update a status modal, import media, and load subtitles.
  • remote.updateModalTitle(), remote.toggleStatusModal(), and remote.updateModalStatus() are examples of controlling the editor's UI state.
  • remote.setProjectName(), remote.setProjectFrameRate(), etc., configure the project's metadata.
  • remote.importSubtitle() and remote.importMedia() are key functions for loading content into the editor.
  • remote.setMediaPeaksPath() and remote.toggleTimeline() control additional visual elements like audio waveforms.

You now have the fundamental structure for embedding and communicating with the Closed Caption Creator IFrame Remote. Proceed to the Functions Reference to explore all available methods for deeper integration.

Support / Feedback

We are committed to ensuring your successful integration of the Closed Caption Creator IFrame Remote. If you encounter any questions during development, require personalized assistance, or have feedback on our documentation or product, please don't hesitate to reach out. We offer dedicated developer training and direct support to help with all aspects of your integration. Visit our Contact Page to connect with our team.

Functions

The Closed Caption Creator IFrame Remote exposes a set of asynchronous methods that your parent application can call via the PenPal connection. These methods allow you to control various aspects of the editor, from loading content to managing project settings and retrieving data.

All calls to these functions should be awaited, as they return Promises.

Function Name Arguments Description Return
setProjectId(id) id: string Sets the unique identifier for the current project. Promise<void>
setProjectName(name) name: string Sets the display name of the current project. Promise<void>
setProjectDescription(description) description: string Sets the description for the current project. Promise<void>
setProjectFrameRate(frameRate) frameRate: number (e.g., 23.976, 25, 29.97, 30) Sets the project's video frame rate. Promise<void>
setProjectDropFrame(dropFrame) dropFrame: boolean Sets whether the project uses drop-frame timecode. Promise<void>
setProjectIncode(incode) incode: string (timecode string, e.g., "00:00:00:00") Sets the project's incode (start timecode). Promise<void>
setProjectState(state) state: object (Partial project state object) Updates multiple project state properties at once. Promise<void>
setMediaPeaksPath(path) path: string (URL to audio peaks JSON) Sets the URL for the audio waveform peaks data to be displayed in the timeline. Promise<void>
setMediaPeaksData(data) data: object (Audio peaks data object) Directly sets the audio waveform peaks data as an object, bypassing a URL fetch. Promise<void>
useFallbackTimeline() None Instructs the timeline to use a fallback visual representation if peaks data is unavailable or problematic. Promise<void>
useDefaultTimeline() None Ensures the timeline attempts to use provided peaks data rather than a fallback. Promise<void>
toggleTimeline(enable) enable: boolean Toggles the visibility of the timeline UI element. If enable is true, shows the timeline. If false, it toggles its current state. Promise<void>
setPoster(thumbnailUrl) thumbnailUrl: string Sets the poster image (thumbnail) for the video player. Promise<void>
importMedia(mediaUrl, thumbnailUrl, mediaType, storageType) mediaUrl: string
thumbnailUrl: string (Optional)
mediaType: string (e.g., "video/mp4", default "video/mp4")
storageType: string (e.g., "Cloud Storage", "Vimeo", "YouTube", "HLS Manifest", default "Cloud Storage")
Loads a video or audio file into the editor from a specified URL. Promise<{ success: boolean, message: string }>
setTranscript(transcript, profile) transcript: object (Transcription data object)
profile: string (Source profile, e.g., "deepgram", default "deepgram")
Sets the raw transcript data to be processed by the editor. Promise<void>
loadTranscript() None Processes the transcript data previously set via setTranscript and imports it into the editor as a new event group. Promise<{ success: boolean, message: string }>
importSubtitle(subtitleUrl, profile, decodeOptions, evgOptions) subtitleUrl: string (URL to subtitle file)
profile: string (Subtitle format profile, e.g., "subRip", "webVtt")
decodeOptions: object (Optional, format-specific decoding options)
evgOptions: object (Optional, event group options like type, name, language)
Loads a subtitle file from a URL into the editor, converting it to the internal project format. Promise<{ success: boolean, message: string }>
exportSubtitle(profile, encodeOptions, saveAsFile) profile: string (Target subtitle format profile)
encodeOptions: object (Optional, format-specific encoding options)
saveAsFile: boolean (If true, triggers a file download; otherwise, returns data)
Exports the current captions from the editor into a specified format. Can return the data or trigger a file download. Promise<{ success: boolean, message: string, data?: string, fileName?: string }>
getMarkers() None Retrieves the current marker data from the editor, including all marker lists and their markers. Promise (Copy of marker state)
setMarkers(markers) markers: object (Marker state object with lists and selected properties) Sets the entire marker state for the editor, allowing you to load custom markers and lists. Promise<void>
createMarkerList(markerList) markerList: { name: string, color?: string } Creates a new named marker list within the editor. Promise<void>
insertMarker(marker, markerListId) marker: object (_Marker object, e.g., { time: number, comment: string })
markerListId: number (Optional, ID of the target marker list, default 0)
Inserts a new marker into a specified marker list. Promise<void>
loadProjectData(ccprj) ccprj: object or string (Closed Caption Project JSON data) Loads a complete Closed Caption Creator project (in .ccprj format) into the editor. Promise<{ success: boolean, message: string }>
getProjectData() None Retrieves the entire current project data from the editor in .ccprj JSON format. Promise (Complete project JSON)

Importing & Exporting Subtitles

A core functionality of the Closed Caption Creator IFrame Remote is the ability to seamlessly import existing subtitle files and export edited captions into various formats. This section details the methods and key parameters involved in these crucial operations.

Importing Subtitles

To load subtitles into the editor, you will use the importSubtitle method. This method is designed to handle a wide array of caption formats and allows for granular control over how the data is interpreted.

importSubtitle(subtitleUrl, profile, decodeOptions, eventGroupOptions)

  • subtitleUrl: 
    • This required parameter specifies the direct URL from which the subtitle file will be read. The editor will fetch the content from this location.
  • profile (Source Profile): 
    • This required string parameter instructs Closed Caption Creator on how to correctly parse and decode the incoming caption data from the subtitleUrl. Each profile corresponds to a specific subtitle format (e.g., "subRip" for SRT, "webVtt" for VTT).
    • A comprehensive list of supported source profiles is available via our API documentation:
      https://api.closedcaptionconverter.com/help/profiles/source
  • decodeOptions:
    • This optional object parameter allows you to provide special, profile-specific settings that influence how the caption data is decoded. For instance, a profile might have options for handling specific character encodings or timecode offsets.
    • While optional, understanding these can be crucial for precise imports. A full list of decode options for each profile is detailed in our API documentation: https://api.closedcaptionconverter.com/help/profiles/all
  • eventGroupOptions:
    • This optional object parameter provides settings for the "Event Group" that will be created or updated within the editor. Event Groups are fundamental for real-time error tracking and validation of subtitle properties.
    • Key properties you can set include:
      • maxChars: Maximum characters per caption event.
      • maxLines: Maximum number of lines per caption event.
      • minDuration: Minimum duration for a caption event.
      • maxDuration: Maximum duration for a caption event.
      • overlap: Defines behavior for overlapping caption events.
      • maxCps: Maximum characters per second (readability check).
      • maxWpm: Maximum words per minute (readability check).
Exporting Subtitles

To retrieve the edited captions from the editor, you will use the exportSubtitle method. This allows you to generate output in your desired target format.

exportSubtitle(profile, encodeOptions, saveAsFile)

  • profile (Target Profile):
    • This required string parameter specifies the format in which the editor should encode the current caption data. This must match one of our supported target profiles.
    • A complete list of supported target profiles is available via our API documentation:
      https://api.closedcaptionconverter.com/help/profiles/target
  • encodeOptions: 
    • Similar to decodeOptions, this optional object parameter provides special, profile-specific settings used by the encoder when generating the output subtitle file. These settings can affect output formatting, metadata inclusion, or specific technical requirements of the target format.
    • A full list of encode options for each profile is available via our API documentation:
      https://api.closedcaptionconverter.com/help/profiles/all
  • saveAsFile:
    • This boolean flag dictates the behavior of the exportSubtitle method.
      • If true, the editor will trigger a file download in the user's browser, allowing them to save the exported subtitle file directly.
      • If false (default), the method will return the file contents (as a string or binary data, depending on the format) within the Promise resolution, allowing your parent application to handle the data programmatically (e.g., upload to cloud storage, display in UI).

More Solutions

Closed Captioning

Create closed captioning and subtitles for your broadcast videos using Closed Caption Creator. Create, edit, and review closed captioning using our intuitive timed-text editor.

Learn More

Translation & Localization

Translate and localize closed captioning, and subtitles in our dedicated Translation UI. View the original source language alongside the translated text to ensure an accurate translation.

Learn More

Transcripts & Dialogue Lists

Create as-broadcast scripts, and dialogue lists with custom notes, tags, Speaker IDs, and more using Closed Caption Creator. Support for Microsoft Word (.docx), CSV, and plaintext formats. 

Learn More

Audio Description & DV

Create lifelike audio descriptions and described video (DV) using the power of synthetic voice. Unlock the ability to create closed captioning and audio descriptions all in one application. 

Learn More

Embed & Extract 608/708 Closed Captioning

Package broadcast-ready files with the CC Embed export option for Closed Caption Creator. Supports MXF, MP4, MOV, and more.

Learn More

File Converter API

Automate your closed caption and subtitle workflows using our dedicated Closed Caption Converter API. Support over 30 different closed caption and subtitle file formats. 

Learn More