UNPKG

@eleven-am/transcoder

Version:

High-performance HLS transcoding library with hardware acceleration, intelligent client management, and distributed processing support for Node.js

211 lines 7.83 kB
"use strict"; /* * @eleven-am/transcoder * Copyright (C) 2025 Roy OSSAI * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.QualityService = void 0; const types_1 = require("./types"); const vQualities = [ types_1.VideoQualityEnum.P240, types_1.VideoQualityEnum.P360, types_1.VideoQualityEnum.P480, types_1.VideoQualityEnum.P720, types_1.VideoQualityEnum.P1080, types_1.VideoQualityEnum.P1440, types_1.VideoQualityEnum.P4K, types_1.VideoQualityEnum.P8K, ]; const aQualities = [ types_1.AudioQualityEnum.AAC, types_1.AudioQualityEnum.ORIGINAL, ]; class QualityService { constructor(videoQualities = vQualities, audioQualities = aQualities) { this.videoQualities = videoQualities; this.audioQualities = audioQualities; this.videoQualityMap = { [types_1.VideoQualityEnum.P240]: { value: types_1.VideoQualityEnum.P240, averageBitrate: 400_000, maxBitrate: 700_000, height: 240, }, [types_1.VideoQualityEnum.P360]: { value: types_1.VideoQualityEnum.P360, averageBitrate: 800_000, maxBitrate: 1_400_000, height: 360, }, [types_1.VideoQualityEnum.P480]: { value: types_1.VideoQualityEnum.P480, averageBitrate: 1_200_000, maxBitrate: 2_100_000, height: 480, }, [types_1.VideoQualityEnum.P720]: { value: types_1.VideoQualityEnum.P720, averageBitrate: 2_400_000, maxBitrate: 4_000_000, height: 720, }, [types_1.VideoQualityEnum.P1080]: { value: types_1.VideoQualityEnum.P1080, averageBitrate: 4_800_000, maxBitrate: 8_000_000, height: 1080, }, [types_1.VideoQualityEnum.P1440]: { value: types_1.VideoQualityEnum.P1440, averageBitrate: 9_600_000, maxBitrate: 12_000_000, height: 1440, }, [types_1.VideoQualityEnum.P4K]: { value: types_1.VideoQualityEnum.P4K, averageBitrate: 16_000_000, maxBitrate: 28_000_000, height: 2160, }, [types_1.VideoQualityEnum.P8K]: { value: types_1.VideoQualityEnum.P8K, averageBitrate: 28_000_000, maxBitrate: 40_000_000, height: 4320, }, [types_1.VideoQualityEnum.ORIGINAL]: { value: types_1.VideoQualityEnum.ORIGINAL, averageBitrate: -1, maxBitrate: -1, height: -1 }, }; this.audioQualityMap = { [types_1.AudioQualityEnum.AAC]: { value: types_1.AudioQualityEnum.AAC, averageBitrate: 128_000, maxBitrate: 192_000 }, [types_1.AudioQualityEnum.ORIGINAL]: { value: types_1.AudioQualityEnum.ORIGINAL, averageBitrate: -1, maxBitrate: -1 }, }; } /** * Determine the appropriate quality for a video * @param video The video to determine quality for * @returns The appropriate quality level */ determineVideoQuality(video) { for (const qualityValue of this.videoQualities) { const quality = this.videoQualityMap[qualityValue]; if (quality.height >= video.height) { return quality; } } return this.videoQualityMap[this.videoQualities[0]]; } /** * Determine the appropriate audio quality for a video * @param audio The video to determine audio quality for * @returns The appropriate audio quality level */ determineAudioQuality(audio) { for (const qualityValue of this.audioQualities) { const quality = this.audioQualityMap[qualityValue]; if (quality.averageBitrate >= audio.bitrate) { return quality; } } return this.audioQualityMap[this.audioQualities[0]]; } /** * Parse a quality string into a Quality object * @param qualityStr The quality string to parse * @throws Error if the quality string is invalid */ parseVideoQuality(qualityStr) { const quality = this.videoQualityMap[qualityStr]; if (!quality) { throw new Error(`Invalid quality: ${qualityStr}`); } return quality; } /** * Parse a quality string into an AudioQuality object * @param qualityStr The quality string to parse * @throws Error if the quality string is invalid */ parseAudioQuality(qualityStr) { const quality = this.audioQualityMap[qualityStr]; if (!quality) { throw new Error(`Invalid quality: ${qualityStr}`); } return quality; } /** * Gets the available qualities for a video * @param video The video to get qualities for * @returns An array of available qualities for the video */ getVideoQualities(video) { const determinedQuality = this.determineVideoQuality(video); const result = []; for (const qualityValue of this.videoQualities) { const quality = this.videoQualityMap[qualityValue]; result.push(quality); if (quality.value === determinedQuality.value) { break; } } return result; } /** * Get the non-transcode video qualities */ getNonTranscodeVideoQualities() { return this.videoQualityMap[types_1.VideoQualityEnum.ORIGINAL]; } /** * Builds a valid audio quality object based on the provided quality and audio info * @param quality The desired audio quality * @param audioInfo The audio info object containing bitrate information */ buildValidAudioQuality(quality, audioInfo) { if (quality === types_1.AudioQualityEnum.ORIGINAL) { return { value: types_1.AudioQualityEnum.ORIGINAL, averageBitrate: audioInfo.bitrate * 1.2, maxBitrate: audioInfo.bitrate * 2, }; } return this.parseAudioQuality(quality); } /** * Builds a valid video quality object based on the provided quality and video info * @param quality The desired video quality * @param videoInfo The video info object containing bitrate and height information */ buildValidVideoQuality(quality, videoInfo) { if (quality === types_1.VideoQualityEnum.ORIGINAL) { return { value: types_1.VideoQualityEnum.ORIGINAL, averageBitrate: videoInfo.bitrate * 1.2, maxBitrate: videoInfo.bitrate * 2, height: videoInfo.height, }; } return this.parseVideoQuality(quality); } } exports.QualityService = QualityService; //# sourceMappingURL=qualityService.js.map