Jump to content

Interactive transcript function

VidPly has a powerful interactive transcript feature that displays video subtitles in a separate window, allowing users to read along, search and jump to specific parts of the video.

VidPly Logo

Features

  • Automatic scrolling – The transcript automatically highlights the current line and scrolls to it
  • Click to jump – Click on any line in the transcript to jump to that moment in the video
  • Movable window – Position the transcript anywhere on the screen (desktop only)
  • Adjust window size – Resize the transcript window using your mouse or keyboard
  • Keyboard navigation – Use the arrow keys to move the transcript window (press ‘D’ to toggle)
  • Keyboard resize mode – Use the arrow keys to adjust the size of the transcript window (press ‘R’ to toggle)
  • Settings menu – Configure drag and resize modes
  • Mobile optimisation – Adapts to mobile screens (< 768px) with an optimised layout
  • Full-screen support – The transcript is intelligently repositioned in full-screen mode
  • Search & Read – Ideal for accessibility and language learning

Quick Start

Enable transcript

 
<video data-vidply data-transcript="true" data-transcript-button="true">
  <source src="video.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en" label="English">
</video>

<script type="module">
  import Player from './dist/prod/vidply.esm.min.js';
</script>
 

That’s it! The transcript button appears in the control bar.

Configuration options

About JavaScript

 
const player = new Player('#video', {
  transcript: true,              // Enable transcript feature
  transcriptButton: true,        // Show transcript button in controls
  transcriptPosition: 'external' // Position mode (currently only 'external')
});
 

About data attributes

 
<video 
  data-vidply
  data-transcript="true"
  data-transcript-button="true"
  src="video.mp4"
>
  <track kind="captions" src="captions.vtt" srclang="en" label="English">
</video>
 

How it works

The transcription feature automatically performs the following steps:

  1. Detects subtitle tracks in your video
  2. Loads the VTT cue text (WebVTT)
  3. Creates an interactive, scrollable window
  4. Highlights the current line based on the video playback time
  5. Scrolls automatically to keep the current line visible

API methods

Show/hide transcript

 
const player = new Player('#video', {
  transcript: true,
  transcriptButton: true
});

// Show transcript window
player.transcriptManager.showTranscript();

// Hide transcript window
player.transcriptManager.hideTranscript();

// Toggle transcript visibility
player.transcriptManager.toggleTranscript();
 

Check status

 
// Check if transcript is visible
if (player.transcriptManager.isVisible) {
  console.log('Transcript is showing');
}
 

Program-controlled operation

 
// Get transcript entries
console.log(player.transcriptManager.transcriptEntries);

// Get current active entry
console.log(player.transcriptManager.currentActiveEntry);
 

User interaction

Click to search

Users can click on any line of the transcript to jump to that point:

 
// This happens automatically, but you can listen for it
player.on('timeupdate', (time) => {
  console.log('User jumped to:', time);
});
 

Drag and resize (desktop)

On desktop (>= 768px), users can:

Drag mode:

  • D key – Toggle keyboard drag mode
  • Arrow keys – Move window in 10-pixel increments (Shift = 50 pixels)
  • Mouse drag – Drag the header of the transcript to change its position
  • Home key – Reset to centre
  • Esc key – Exit drag mode

Resize mode:

  • R key – Switch to resize mode via the keyboard
  • Arrow keys – Change window size in 10-pixel increments (Shift = 50 pixels)
  • Resizing with the mouse – Drag the resize handles at the edges of the window
  • Esc key – Exit resize mode

Settings menu:

  • Click the settings icon (⚙️) in the header of the transcript
  • Toggle between drag mode and resize mode
  • Close the transcript window

Behaviour on mobile devices

On mobile devices (< 768px breakpoint):

  • The transcript is displayed below the video player
  • Positioned within the document flow (cannot be moved or resized)
  • Optimised for scrolling and reading
  • Minimum width: 300px

Positioning modes

Desktop (non-full screen)

  • Displayed next to the video player
  • Can be dragged to any position
  • Height matches the video height

Full-screen mode

  • Located in the bottom right-hand corner
  • Hovers over the video
  • Leaves space for controls

Mobile

  • Below the video and controls
  • Full width
  • Maximum height of 400px
  • Part of the page flow

Keyboard shortcuts

Global keyboard shortcuts (Player in focus)

KeyAction
TShow/hide transcript window
DToggle drag mode (when transcript is visible)
RToggle resize mode (when transcript is visible)

Drag mode (D key – must be activated first)

KeyAction
Move window (10px)
Shift + Arrow keyMove window (50px)
HomeReset to centre
EscExit drag mode

Resize mode (R key – must be activated first)

KeyAction
Adjust width (10px)
Adjust height (10px)
Shift + Arrow keyResize (50px)
EscExit resize mode

Transcript entries

KeyAction
Enter / SpacebarJump to this point (if the entry is in focus)
TabNavigate through the transcript entries

Layout of the transcript

Custom colours

 
/* Transcript window */
.vidply-transcript-window {
  background: rgba(20, 20, 30, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* Header */
.vidply-transcript-header {
  background: rgba(30, 30, 40, 0.95);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

/* Transcript entries */
.vidply-transcript-entry {
  padding: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

/* Active entry */
.vidply-transcript-entry-active {
  background: rgba(59, 130, 246, 0.2);
  border-left: 3px solid #3b82f6;
}

/* Timestamp */
.vidply-transcript-time {
  color: #60a5fa;
  font-weight: 600;
}
 

Full example

 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Transcript Example</title>
  <link rel="stylesheet" href="dist/vidply.min.css">
  
  <style>
    body {
      font-family: system-ui, sans-serif;
      padding: 20px;
      background: #111;
      color: #fff;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    h1 {
      margin-bottom: 20px;
    }
    
    /* Custom transcript styling */
    .vidply-transcript-window {
      background: linear-gradient(135deg, rgba(30, 30, 50, 0.98), rgba(20, 20, 40, 0.98));
      backdrop-filter: blur(10px);
    }
    
    .vidply-transcript-entry-active {
      background: linear-gradient(90deg, rgba(139, 92, 246, 0.2), rgba(59, 130, 246, 0.2));
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>Video with Interactive Transcript</h1>
    
    <video 
      id="my-video"
      data-vidply
      data-transcript="true"
      data-transcript-button="true"
      width="800" 
      height="450"
    >
      <source src="video.mp4" type="video/mp4">
      <track kind="captions" src="captions-en.vtt" srclang="en" label="English" default>
      <track kind="captions" src="captions-es.vtt" srclang="es" label="Español">
    </video>
    
    <div style="margin-top: 20px;">
      <button id="toggleTranscript">Toggle Transcript</button>
    </div>
  </div>

  <script type="module">
    import Player from './dist/prod/vidply.esm.min.js';
    
    // Player is auto-initialized via data-vidply
    
    // Get player instance
    const videoElement = document.getElementById('my-video');
    const player = videoElement.vidply; // Player instance stored on the media element

    // Or find it manually
    const allPlayers = document.querySelectorAll('[data-vidply]');
    // const player = allPlayers[0].vidply;
    
    // Manual toggle button
    document.getElementById('toggleTranscript').addEventListener('click', () => {
      if (player && player.transcriptManager) {
        player.transcriptManager.toggleTranscript();
      }
    });
    
    // Listen for transcript interactions
    document.addEventListener('DOMContentLoaded', () => {
      // Wait a moment for player to initialize
      setTimeout(() => {
        const container = document.querySelector('.vidply-player');
        const video = container?.querySelector('video, audio');
        if (video && video.vidply) {
          const p = video.vidply;
          
          p.on('timeupdate', (time) => {
            // User can see which line is active
            if (p.transcriptManager && p.transcriptManager.currentActiveEntry) {
              console.log('Active transcript:', p.transcriptManager.currentActiveEntry.cue.text);
            }
          });
        }
      }, 1000);
    });
  </script>
</body>
</html>
 

Use cases

1. Accessibility

  • Users of screen readers can read the transcript text
  • Deaf or hard-of-hearing users have full access to the text
  • Users in noisy environments can read instead of listening

2. Language learning

  • Follow the native speakers
  • Click here to replay difficult sections
  • Read and listen at the same time

3. Search & Navigation

  • Quickly skim through content
  • Find specific topics
  • Jump to relevant sections

4. Notes

  • Cite exact quotations
  • Copy text for quotations
  • Learning support for educational content

5. SEO & discoverability

  • Video content becomes text-searchable
  • Better indexing for accessibility
  • Improved discoverability of content

Requirements

Subtitle track required

At least one subtitle track is required for the transcription function:

 
<track kind="captions" src="captions.vtt" srclang="en" label="English">
<!-- or -->
<track kind="subtitles" src="subtitles.vtt" srclang="en" label="English">
 

Note: kind="descriptions" or kind="chapters" Tracks are NOT used for transcripts.

Supported streaming formats

Platform / FormatSubtitle typeTranscript support
HTML5 (MP4/WebM)WebVTTYes
HLS (.m3u8) — hls.js (Chrome / Firefox / Edge / Desktop Safari)WebVTTYes (Cues are loaded incrementally whilst segments are buffered; Hls.Events.SUBTITLE_FRAG_PROCESSED replay textcuesupdate)
HLS (.m3u8) — Native HLS on iOS / iPadOS SafariWebVTT (via native TextTrack API)Yes — VidPly integrates the browser’s native HLS subtitles into the subtitle menu, the transcript window and the quality menu
DASH (.mpd)WebVTTYes (cues are loaded incrementally whilst segments are buffered)
DASH (.mpd)TTML / stppNo (TTML is rendered natively by dash.js; the transcript button is hidden)
 

iOS / iPadOS: Even though hls.js it cannot run on iOS (no MSE), VidPly waits addtrack / removetrack / loadedmetadata for the native HTMLMediaElement.textTracks collection and displays each subtitle presentation via the same subtitle menu and interactive transcription as on desktop. Transcript-on-iOS now works for live and adaptive HLS streams.

 

For DASH streams with TTML subtitles, the subtitles are displayed on screen by dash.js, but the interactive transcript is not available. If you require transcript support for DASH, use WebVTT subtitle tracks.

WebVTT format

Subtitles must be in WebVTT format:

 
WEBVTT

00:00:00.000 --> 00:00:05.000
Welcome to this video tutorial.

00:00:05.000 --> 00:00:10.000
Today we'll learn about VidPly's transcript feature.

00:00:10.000 --> 00:00:15.000
It's a powerful tool for accessibility and learning.
 

Browser support

The transcription feature works in all modern browsers:

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Mobile browsers (iOS Safari, Chrome Android)

Troubleshooting

The ‘Transcript’ button is not displayed

Cause: No subtitle tracks were detected

Solution:

 
<!-- Add at least one caption track -->
<track kind="captions" src="captions.vtt" srclang="en" label="English">
 

Transcript displays “Loading...”

Cause: The VTT file is taking a long time to load or the path is incorrect

Solutions:

  1. Check that the file path is correct
  2. Check the CORS headers if loading from a different domain
  3. Check that the VTT file format is valid

Transcript cannot be moved on mobile devices

Expected: On mobile devices (< 768px), the transcript is NOT scrollable. It is positioned in the page flow below the video.

Transcript does not scroll automatically

Cause: JavaScript error or subtitle track not in hidden mode

Solution: Check the browser console for errors. The Transcript Manager automatically sets the track mode to hidden.

Advanced: External transcript container

You can display the transcript in a custom container (future feature):

 
const player = new Player('#video', {
  transcript: true,
  transcriptPosition: 'external',
  transcriptContainer: '#my-transcript-container'
});
 
<div id="my-transcript-container"></div>
 

Note: This feature is partially implemented. Currently, the transcript is always displayed next to or below the video.

Notes on performance

  • Transcript entries are generated as required when the transcript is displayed for the first time
  • Automatic scrolling uses efficient scrollIntoView with smooth behaviour
  • Event listeners are cleared when the transcript is destroyed
  • No impact on performance when the transcript is not visible

Accessibility features

Keyboard accessibility – Full keyboard navigation
ARIA labels – Correct role and aria-label attributes
Focus management – Logical focus order
Screen reader-friendly – Semantic HTML structure
High contrast – Takes account of the system’s colour settings
Touch-friendly – Large touch targets (at least 44px)

Best practice

  1. Always provide subtitles – even automatically generated subtitles are better than none at all
  2. Use descriptive captions – Help users identify the languages of the audio tracks
  3. Test on mobile devices – ensure the transcript is readable on small screens
  4. Consider positioning – Placing the transcript next to the video works well on desktop
  5. Keep the design consistent – Match the design to your website whilst ensuring good readability

Demo

Take a look at some working examples:

  • demo/demo.html - Basic use of transcripts
  • demo/sign-language-demo.html - Transcript with sign language video

Created with Vanilla JavaScript by Matthias Peltzer

Share page