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.
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.
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.
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.
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:
This approach ensures a robust and flexible integration, enabling you to build highly interactive and customized captioning workflows.
To help you begin immediately, here are two essential links:
Dive into the Getting Started section below to begin your integration.
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.
To follow along, you should have a basic understanding of HTML and JavaScript.
Import PenPal JS using NPM, or CDN.
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<script src="https://unpkg.com/penpal@^7/dist/penpal.min.js"></script>
</body>
</html>
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.
<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>
document.addEventListener('DOMContentLoaded', () => {
const iframe = document.getElementById('editor');
});
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.
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);
});
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.
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!",
});
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.
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.
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 |
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 |
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.
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)
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)
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 MoreTranslate 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 MoreCreate 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 MoreCreate 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 MorePackage broadcast-ready files with the CC Embed export option for Closed Caption Creator. Supports MXF, MP4, MOV, and more.
Learn MoreAutomate 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