Video Services Integration (Mux, api.video)
Relevant source files
The following files were used as context for generating this wiki page:
- apps/api/src/module/video-services/streamService.module.ts
- apps/api/src/module/video-services/mux/mux.service.ts
- apps/api/src/module/video-services/api-video/api-video.service.ts
- apps/extensions/src/content/utilities/upload/services/uploadToMux.ts
- apps/api/src/module/video-services/streamService.service.ts
- apps/extensions/src/app/services/api/videoStreaming.ts
- apps/extensions/src/content/panel/hooks/useManageVideoData.ts
- apps/api/src/module/video/video.service.ts
The Ever Rec platform integrates with third-party video services, specifically Mux and api.video, to handle video uploading, processing, and streaming. This approach offloads the heavy lifting of video transcoding and delivery from the application's backend, allowing for a more scalable and robust video infrastructure. The system is designed with an abstraction layer that allows for multiple video service providers to be used interchangeably.
This document outlines the architecture, data flow, and key components of the video services integration. The primary goal is to provide a seamless experience for users to upload and stream video content, while the backend manages the interaction with the chosen video provider.
Architecture Overview
The video service integration is split between the client-side (the extensions and portal apps) and the backend (api app). The backend contains a dedicated NestJS module, StreamServiceModule, which orchestrates interactions with the external video providers.
The general flow is as follows:
- The client requests a direct upload URL from the API.
- The API contacts the configured video service (Mux or api.video) to generate this URL.
- The client uploads the video file directly to the third-party service, bypassing the Ever Rec API server.
- Once the upload is complete, the client notifies the API, which then saves the video's metadata (like asset ID and playback URLs) to the Firebase database.
This diagram shows the high-level interaction between the components.
Backend Services
The core of the integration resides in the apps/api project within the StreamServiceModule.
Sources: apps/api/src/module/video-services/streamService.module.ts
This diagram illustrates the relationship between the main services in the backend. StreamServiceService acts as a facade, delegating calls to the appropriate concrete implementation (MuxService or ApiVideoService) based on the serviceType.
Sources: apps/api/src/module/video-services/streamService.service.ts, apps/api/src/module/video-services/mux/mux.service.ts, apps/api/src/module/video-services/api-video/api-video.service.ts
StreamServiceService
This service acts as an orchestrator. It contains the business logic for saving and updating video metadata in the database and decides which underlying video provider service to call.
saveVideoData()/updateVideoData(): These methods create or update a video record in Firebase. They store theIStreamingDbDataobject and trigger an asynchronous background job (fixVideoAndUploadToBucket) to also save a copy of the video to the internal Firebase Storage bucket as a backup and for direct download.deleteAsset()/copyAsset(): These methods are facades that call the corresponding method on eitherMuxServiceorApiVideoServicebased on theserviceTypeparameter.
Sources: apps/api/src/module/video-services/streamService.service.ts:18-138
MuxService
This service implements the integration with the Mux video platform using the @mux/mux-node SDK.
- Configuration: It is initialized with
MUX_TOKEN_IDandMUX_TOKEN_SECRETfrom the environment configuration. getDirectUpload(): Creates a new direct upload asset in Mux and returns the secureurlfor the client to upload to, along with the uploadid.getPlaybackStatus(): Polls a Mux asset's status (ready,errored,preparing) and updates the video'splaybackStatusin the Firebase database accordingly.deleteAsset(): Deletes a video asset from Mux.
Sources: apps/api/src/module/video-services/mux/mux.service.ts
ApiVideoService
This service implements the integration with the api.video platform using the @api.video/nodejs-client SDK.
- Configuration: It is initialized with
APIVIDEO_TOKEN_IDfrom the environment configuration. getDirectUpload(): Creates a new video object and an upload token in api.video, returning thevideoIdandtokenfor the client to use for uploading.getPlaybackStatus(): Checks the encoding and ingest status of a video in api.video to determine if it's ready for playback.deleteAsset(): Deletes a video asset from api.video.
Sources: apps/api/src/module/video-services/api-video/api-video.service.ts
Video Upload Data Flow
The video upload process is designed to be efficient by uploading large video files directly from the client to the third-party provider.
This sequence diagram details the entire process, from the user action in the browser extension to the final data being saved.
Key Data Structures & Enums
IStreamingDbData
This interface defines the structure of the video streaming metadata stored in the Firebase Realtime Database for each video.
| Field | Type | Description |
|---|---|---|
serviceType | VideoServicesEnum | The video service provider used (e.g., MUX, API_VIDEO). |
assetId | string | The unique identifier for the asset in the third-party service. |
thumbnailUrl | string | A URL to the video's thumbnail image. |
playbackUrl | string | The HLS (.m3u8) URL for streaming the video. |
playbackStatus | PlaybackStatusEnum | The current processing status of the video (PREPARING, READY, ERRORED). |
downloadStatus | PlaybackStatusEnum | The status of the downloadable MP4 version. |
downloadUrl | string | A URL to a downloadable MP4 version of the video. |
videoTitle? | string | The title of the video (used during creation). |
videoDuration? | string | The duration of the video (used during creation). |
Sources: apps/api/src/module/video-services/streamService.service.ts:33-46, apps/extensions/src/content/utilities/upload/services/uploadToMux.ts:46-57
Enums
| Enum | Values | Description |
|---|---|---|
VideoServicesEnum | MUX, API_VIDEO | Identifies the external video service provider. |
PlaybackStatusEnum | PREPARING, READY, ERRORED | Represents the lifecycle status of a video asset. |
Sources: apps/api/src/module/video-services/mux/mux.service.ts:9, apps/extensions/src/content/utilities/upload/services/uploadToMux.ts:7
API Endpoints
The following API endpoints are central to the video service integration.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/stream/default-stream-service | Gets the default video streaming service configured on the backend. |
GET | /api/v1/{service}/direct-upload | Requests a direct upload URL/token from the specified service. |
GET | /api/v1/{service}/uploaded-asset/{uploadId} | Confirms a successful upload and retrieves the asset details. |
POST | /api/v1/stream/save-data | Saves the video metadata to the database after a successful upload. |
POST | /api/v1/stream/save-data/{videoId} | Updates an existing video's metadata (e.g., after trimming). |
GET | /api/v1/{service}/get-status/{videoId}/{assetId} | Used for polling the processing status of a video asset. |
Sources: apps/extensions/src/app/services/api/videoStreaming.ts, apps/portal/app/services/api/videoStreaming.ts
Client-Side Implementation
On the client side, primarily within the apps/extensions project, several hooks and services manage the upload flow.
useManageVideoDataHook: This React hook orchestrates the video upload process when a new recording is completed. It callsgetDefaultStreamServiceto determine which provider to use and then invokesuploadVideoToService.
Sources: apps/extensions/src/content/panel/hooks/useManageVideoData.ts:60-75uploadToMux.ts: This service contains the specific logic for uploading to Mux. It demonstrates the full client-side flow:- Calls
directUpload()to get the upload URL from the API. - Uses
@mux/upchunkto upload the file in chunks directly to the Mux endpoint. - Listens for
successandprogressevents fromupChunk. - On success, it calls
uploadedAsset()to get the final asset ID. - Finally, it calls
saveVideoStreamData()to post all the streaming metadata to the Ever Rec API.
Sources: apps/extensions/src/content/utilities/upload/services/uploadToMux.ts
- Calls
Summary
The video services integration in Ever Rec is a well-architected system that leverages third-party providers (Mux and api.video) to handle complex video processing tasks. By using a direct-to-cloud upload pattern, it minimizes the load on the application's own backend, ensuring scalability. The use of a service-oriented architecture with a clear abstraction layer (StreamServiceService) makes the system maintainable and extensible, allowing for the potential addition of other video providers in the future with minimal changes to the core application logic.