Skip to main content

Overview

EmbyClient extends MediaClient to provide integration with Emby and Jellyfin media servers. It handles authentication, library browsing, video streaming, and playlist-based favorites.

Constructor

import { EmbyClient } from './services/EmbyClient';

const client = new EmbyClient(config);
config
ServerConfig
required
Server configuration with Emby server details

Authentication

authenticate

Authenticates with an Emby/Jellyfin server using username and password.
authenticate(username: string, password: string): Promise<ServerConfig>
username
string
required
Emby username
password
string
required
Emby password
url
string
Server URL
username
string
Authenticated user’s name
userId
string
User ID from Emby
token
string
Access token for API requests
serverType
'emby'
Always returns ‘emby’

Example

const config: ServerConfig = {
  url: 'https://emby.example.com',
  username: '',
  token: '',
  userId: '',
  serverType: 'emby'
};

const client = new EmbyClient(config);
const authConfig = await client.authenticate('myusername', 'mypassword');

console.log(authConfig.token); // Access token for future requests

Library Management

getLibraries

Fetches all video libraries available to the authenticated user.
getLibraries(): Promise<EmbyLibrary[]>
return
Promise<EmbyLibrary[]>
Array of library objects

Example

const libraries = await client.getLibraries();

libraries.forEach(lib => {
  console.log(`${lib.Name} (${lib.Id})`);
});

Video Retrieval

getVideos

Fetches videos from a library with advanced filtering and pagination.
getVideos(
  parentId: string | undefined,
  libraryName: string,
  feedType: FeedType,
  skip: number,
  limit: number,
  orientationMode: OrientationMode
): Promise<VideoResponse>
parentId
string | undefined
Library ID to fetch from (undefined for favorites feed)
libraryName
string
required
Name of the library for playlist lookups
feedType
FeedType
required
  • 'latest': Sorted by DateCreated descending
  • 'random': Random shuffle
  • 'favorites': Items from Tok playlist
skip
number
required
Starting index for pagination
limit
number
required
Number of items to fetch (batch size: 50 for latest, 80 for random)
orientationMode
OrientationMode
required
  • 'vertical': Only videos with height >= width * 0.8
  • 'horizontal': Only videos with width > height
  • 'both': No filtering
items
EmbyItem[]
Array of video items
nextStartIndex
number
Index for the next page of results
totalCount
number
Total number of items available

Example

const response = await client.getVideos(
  'library-id-123',
  'Movies',
  'latest',
  0,
  15,
  'vertical'
);

console.log(`Loaded ${response.items.length} of ${response.totalCount} videos`);
response.items.forEach(video => {
  console.log(video.Name);
});

Media URLs

getVideoUrl

Generates direct streaming URL for a video.
getVideoUrl(item: EmbyItem): string
item
EmbyItem
required
Video item to stream
return
string
Direct MP4 stream URL with authentication token

getImageUrl

Generates URL for video thumbnail or backdrop.
getImageUrl(
  itemId: string,
  tag?: string,
  type?: 'Primary' | 'Backdrop'
): string
itemId
string
required
Media item ID
tag
string
Image tag from item.ImageTags
type
'Primary' | 'Backdrop'
default:"'Primary'"
Image type to fetch
return
string
Image URL with 800px max width, or empty string if no tag

Example

const videoUrl = client.getVideoUrl(video);
const thumbnailUrl = client.getImageUrl(
  video.Id,
  video.ImageTags?.Primary,
  'Primary'
);

// Use in video element
<video src={videoUrl} poster={thumbnailUrl} />

Favorites Management

EmbyClient uses playlists named Tok-{LibraryName} to store favorites.

getFavorites

Retrieves all favorited item IDs for a library.
getFavorites(libraryName: string): Promise<Set<string>>
libraryName
string
required
Name of the library
return
Promise<Set<string>>
Set of item IDs in the Tok playlist

toggleFavorite

Adds or removes an item from the favorites playlist.
toggleFavorite(
  itemId: string,
  isFavorite: boolean,
  libraryName: string
): Promise<void>
itemId
string
required
ID of the video item
isFavorite
boolean
required
Current status: true = currently favorited (will remove), false = not favorited (will add)
libraryName
string
required
Library name for playlist lookup/creation

Example

// Load favorites
const favoriteIds = await client.getFavorites('Movies');
console.log(`${favoriteIds.size} favorites`);

// Toggle favorite status
const isFavorite = favoriteIds.has(video.Id);
await client.toggleFavorite(video.Id, isFavorite, 'Movies');

Complete Usage Example

import { ClientFactory } from './services/clientFactory';

// Authenticate
const config = await ClientFactory.authenticate(
  'emby',
  'https://emby.example.com',
  'username',
  'password'
);

const client = ClientFactory.create(config);

// Get libraries
const libraries = await client.getLibraries();
const moviesLib = libraries.find(l => l.Name === 'Movies');

// Load favorites
const favoriteIds = await client.getFavorites(moviesLib.Name);

// Fetch vertical videos
const { items, totalCount } = await client.getVideos(
  moviesLib.Id,
  moviesLib.Name,
  'latest',
  0,
  15,
  'vertical'
);

// Display videos
items.forEach(video => {
  const url = client.getVideoUrl(video);
  const thumb = client.getImageUrl(video.Id, video.ImageTags?.Primary);
  const isFav = favoriteIds.has(video.Id);
  
  console.log(`${video.Name} - Favorite: ${isFav}`);
});

// Add to favorites
await client.toggleFavorite(items[0].Id, false, moviesLib.Name);

Implementation Details

Headers

All requests include:
  • Content-Type: application/json
  • X-Emby-Authorization with MediaBrowser client info and token

Orientation Filtering

Videos are filtered based on aspect ratio:
  • Vertical: height >= width * 0.8 (includes 4:5, 9:16, etc.)
  • Horizontal: width > height
  • Both: No filtering applied

Playlist Creation

Playlists are automatically created when adding the first favorite to a library. Format: Tok-{LibraryName}

See Also

Build docs developers (and LLMs) love