Overview
FolderServerClient extends MediaClient to provide integration with EmbyTok’s folder-based streaming server. It supports local file browsing, orientation filtering, and localStorage-based favorites.
Constructor
import { FolderServerClient } from './services/FolderServerClient';
const client = new FolderServerClient(config);
Server configuration with folder server details
Authentication
authenticate
Connects to the folder server and selects a streaming service.
authenticate(username: string, password: string): Promise<ServerConfig>
Username (used for display, defaults to ‘Folder User’)
Service ID or name to use (optional - will use current/first service if not provided)
Username or ‘Folder User’ if not provided
Service ID (used for API requests)
Example
const config: ServerConfig = {
url: 'http://localhost:3000',
username: '',
token: '',
userId: '',
serverType: 'folder'
};
const client = new FolderServerClient(config);
// Connect to server (auto-selects service)
const authConfig = await client.authenticate('User', '');
// Or specify a service
const authConfig = await client.authenticate('User', 'service-id-123');
Library Management
getLibraries
Fetches available folder libraries from the server.
getLibraries(): Promise<EmbyLibrary[]>
Example
const libraries = await client.getLibraries();
libraries.forEach(lib => {
console.log(`${lib.Name} (${lib.Id})`);
});
Video Retrieval
getVideos
Fetches videos from the folder server with server-side filtering.
getVideos(
parentId: string | undefined,
libraryName: string,
feedType: FeedType,
skip: number,
limit: number,
orientationMode: OrientationMode
): Promise<VideoResponse>
Library ID to fetch from (optional for favorites)
Library name (not used, included for interface compatibility)
'latest': Server-side latest sort
'random': Server-side random shuffle
'favorites': Client-side filtering from localStorage
Starting index for pagination
Number of items to return
Server-side orientation filter: ‘vertical’, ‘horizontal’, or ‘both’
Total number of items available
Example
const response = await client.getVideos(
'library-123',
'',
'latest',
0,
15,
'vertical'
);
console.log(`Loaded ${response.items.length} of ${response.totalCount} videos`);
For favorites feed, the client fetches up to 5000 items and filters client-side using localStorage favorites.
getVideoUrl
Generates streaming URL for a video file.
getVideoUrl(item: EmbyItem): string
Streaming endpoint URL with service ID
getImageUrl
Not supported for folder server (returns empty string).
getImageUrl(
itemId: string,
tag?: string,
type?: 'Primary' | 'Backdrop'
): string
Always returns empty string
Example
const videoUrl = client.getVideoUrl(video);
// http://localhost:3000/api/folder/stream/video-id-123?serviceId=service-id
const thumbnailUrl = client.getImageUrl(video.Id);
// '' (empty - no thumbnails for folder server)
Favorites Management
FolderServerClient stores favorites in localStorage instead of server-side playlists.
getFavorites
Retrieves favorited item IDs from localStorage.
getFavorites(libraryName: string): Promise<Set<string>>
Library name (not used, included for interface compatibility)
Set of item IDs stored in localStorage
toggleFavorite
Toggles favorite status in localStorage.
toggleFavorite(
itemId: string,
isFavorite: boolean,
libraryName: string
): Promise<void>
Current status: true = remove from favorites, false = add to favorites
Library name (not used, included for interface compatibility)
Example
// Load favorites
const favoriteIds = await client.getFavorites('');
console.log(`${favoriteIds.size} favorites`);
// Toggle favorite
const isFavorite = favoriteIds.has(video.Id);
await client.toggleFavorite(video.Id, isFavorite, '');
embytokFolderFavorites:{serverUrl}:{serviceId}
This allows different favorite lists per server and service.
Complete Usage Example
import { ClientFactory } from './services/clientFactory';
// Authenticate with folder server
const config = await ClientFactory.authenticate(
'folder',
'http://localhost:3000',
'User',
'' // Auto-select service
);
const client = ClientFactory.create(config);
// Get libraries
const libraries = await client.getLibraries();
const firstLib = libraries[0];
// Load latest vertical videos
const { items, totalCount } = await client.getVideos(
firstLib.Id,
'',
'latest',
0,
15,
'vertical'
);
// Check favorites
const favoriteIds = await client.getFavorites('');
items.forEach(video => {
const url = client.getVideoUrl(video);
const isFav = favoriteIds.has(video.Id);
console.log(`${video.Name} - Favorite: ${isFav}`);
console.log(`Stream: ${url}`);
});
// Add first video to favorites
await client.toggleFavorite(items[0].Id, false, '');
API Endpoints
The client communicates with these folder server endpoints:
Ping
GET /api/folder/ping
Response: { ok: boolean }
Services
GET /api/folder/services
Response: {
items: Array<{ id: string, name: string, isActive?: boolean }>,
currentServiceId?: string
}
Libraries
GET /api/folder/libraries?serviceId={serviceId}
Response: { items: EmbyLibrary[] }
Videos
GET /api/folder/videos?serviceId={serviceId}&libraryId={libraryId}&feedType={feedType}&skip={skip}&limit={limit}&orientationMode={orientationMode}
Response: {
items: EmbyItem[],
totalCount: number,
nextStartIndex: number
}
Stream
GET /api/folder/stream/{itemId}?serviceId={serviceId}
Response: Video file stream
Implementation Details
Service ID
The service ID is stored in both token and userId fields of ServerConfig and appended to all API requests as a query parameter.
Favorites Storage
Favorites are stored in localStorage as JSON arrays:
["video-id-1", "video-id-2", "video-id-3"]
Favorites Feed
When feedType === 'favorites', the client:
- Fetches up to 5000 items from the ‘latest’ feed
- Filters client-side using localStorage favorites
- Paginates the filtered results
This approach works well for moderate-sized libraries.
See Also