Skip to main content
YouTube is the most feature-rich platform supported by OpenTogetherTube, with full support for individual videos, playlists, channels, and video search.

Features

Individual Videos

Standard videos, Shorts, and premieres

Playlists

Public playlists with automatic preview

Channels

Channel uploads, custom URLs, and handles

Video Search

Search YouTube directly from OTT

Supported URL Formats

The YouTube adapter recognizes these URL patterns:

Individual Videos

https://www.youtube.com/watch?v=VIDEO_ID
https://youtu.be/VIDEO_ID
https://www.youtube.com/shorts/VIDEO_ID
https://www.youtube.com/live/VIDEO_ID
https://studio.youtube.com/video/VIDEO_ID

Playlists

https://www.youtube.com/playlist?list=PLAYLIST_ID
https://www.youtube.com/watch?v=VIDEO_ID&list=PLAYLIST_ID
When a video URL includes a playlist ID (except private playlists like “LL” or “WL”), OTT will load the entire playlist with that video highlighted.

Channels

https://www.youtube.com/@HANDLE
https://www.youtube.com/channel/CHANNEL_ID
https://www.youtube.com/c/CUSTOM_URL
https://www.youtube.com/user/USERNAME

API Key Setup

A YouTube Data API v3 key is required for YouTube support. Without it, YouTube videos cannot be added.

Getting an API Key

  1. Go to Google Cloud Console
  2. Create a new project or select an existing one
  3. Enable the YouTube Data API v3
  4. Go to Credentials and create an API Key
  5. (Optional but recommended) Restrict the key to YouTube Data API v3

Configuration

Add your API key to your configuration file:
[info_extractor]
  [info_extractor.youtube]
    api_key = "YOUR_API_KEY_HERE"

Quota Limits

YouTube API has daily quota limits:
  • Default quota: 10,000 units per day
  • Video metadata request: ~3 units
  • Playlist request: ~3 units
  • Search request: ~100 units
With default quota, you can fetch approximately 3,000 videos per day. If you run out of quota, OTT will attempt a fallback method to extract video duration without the API.

Fallback Method

When the API quota is exceeded, OpenTogetherTube automatically attempts a fallback method:
  • Scrapes the YouTube video page directly
  • Extracts duration from page metadata
  • Only works for video duration (not title, description, or thumbnail)
  • Less reliable than the API method
The fallback is implemented in youtube.ts:649-663 and uses regex patterns to extract video length from the HTML response.

Metadata Extraction

The YouTube adapter fetches comprehensive video metadata:
PropertyAPI PartDescription
TitlesnippetVideo title
DescriptionsnippetVideo description (can be truncated)
ThumbnailsnippetMedium or default thumbnail
DurationcontentDetailsVideo length in seconds
ChannelsnippetChannel name

Description Truncation

You can configure description length limits to reduce storage:
[info_extractor]
  [info_extractor.youtube]
    truncate_description = 500

Playlist & Channel Handling

Playlist Preview

When adding a playlist:
  1. First 50 videos are fetched (configurable)
  2. Preview shown to user
  3. User confirms before adding to queue
  4. Private videos are automatically skipped

Channel Uploads

Channel URLs are converted to the channel’s “uploads” playlist:
  1. Channel ID is resolved (may require web scraping for handles/custom URLs)
  2. Uploads playlist ID is retrieved from channel metadata
  3. Playlist ID is cached in Redis for future requests
  4. Videos are fetched from the uploads playlist
Channel playlist IDs are cached to avoid repeated API calls. The cache key format is ytchannel:{type}:{id}.

Search Functionality

OpenTogetherTube can search YouTube directly:
// Search parameters (from youtube.ts:683-699)
params: {
  q: query,                    // Search query
  type: "video",               // Only videos
  maxResults: 10,              // Configurable limit
  safeSearch: "none",          // No filtering
  videoEmbeddable: true,       // Must be embeddable
  videoSyndicated: true,       // Must allow playback outside YouTube
  eventType: "none"            // Exclude livestreams
}
Search requests consume 100 quota units each, which is significantly more than metadata requests.

Limitations

Not Supported

Livestreams

Active livestreams and premieres are automatically filtered out

Private Videos

Private and unlisted videos in playlists are skipped

Age-Restricted

May not work without authentication

Region-Locked

Depends on server location

Livestream Detection

The adapter checks the liveBroadcastContent field:
  • none = regular video (supported)
  • live = active livestream (blocked)
  • upcoming = scheduled premiere (blocked)
Implementation in youtube.ts:474-486:
if (item.snippet && item.snippet.liveBroadcastContent !== "none") {
  log.debug(`found liveBroadcastContent=${item.snippet.liveBroadcastContent}, skipping`);
  foundLivestream = true;
  continue;
}

Caching

YouTube metadata is cache-safe (isCacheSafe: true), meaning:
  • Video metadata is stored in the database
  • Cached data can be reused for future requests
  • Reduces API quota consumption
  • Cache is updated when video is re-added

Error Handling

Common errors and their meanings:
ErrorCauseSolution
OutOfQuotaExceptionDaily API quota exceededWait 24 hours or enable fallback
VideoNotFoundExceptionVideo doesn’t exist or is privateCheck URL and video availability
InvalidVideoIdExceptionMalformed video IDVerify URL format
UnsupportedVideoTypeLivestream detectedOnly VOD videos are supported

Configuration Options

Full configuration example:
[info_extractor]
  [info_extractor.youtube]
    api_key = "YOUR_API_KEY_HERE"
    truncate_description = 500

[add_preview]
  playlist_results_count = 50
  
  [add_preview.search]
    results_count = 10

Implementation Details

The YouTube adapter is implemented in server/services/youtube.ts and includes:
  • API Client: Uses axios with base URL https://www.googleapis.com/youtube/v3
  • Redis Integration: Caches channel-to-playlist mappings
  • Bulk Operations: Supports fetching up to 50 videos in a single API call
  • Partial Metadata: Can fetch only specific fields to reduce quota usage
  • Error Recovery: Automatic fallback when quota is exceeded
Key methods:
  • canHandleURL(): URL pattern matching (line 158-177)
  • getVideoId(): Extract video ID from various URL formats (line 192-205)
  • fetchVideoInfo(): Single video metadata (line 249-256)
  • fetchManyVideoInfo(): Bulk video metadata (line 258-276)
  • fetchPlaylistVideos(): Playlist contents (line 374-427)
  • searchVideos(): YouTube search (line 683-715)

Best Practices

1

Restrict API Key

Limit your API key to only YouTube Data API v3 and your server’s IP address
2

Monitor Quota

Check your quota usage in Google Cloud Console regularly
3

Enable Caching

Ensure Redis is configured to cache video metadata and reduce API calls
4

Configure Limits

Adjust playlist preview counts based on your usage patterns

Build docs developers (and LLMs) love