From 5b69558d06d246c437f141de8fb52f5f817a9241 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Tue, 26 Mar 2024 21:42:10 +0500 Subject: [PATCH] feat: add helper filters for hls manifest --- lib/dash.js | 43 +++++++++++-------------------------------- lib/hls.js | 10 ++++++++++ lib/track.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 4 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 lib/track.js diff --git a/lib/dash.js b/lib/dash.js index 4d452fc..e3d64d7 100644 --- a/lib/dash.js +++ b/lib/dash.js @@ -1,7 +1,13 @@ 'use strict'; const mpdParser = require('mpd-parser'); -const { parseBitrate, parseSize, getWidth, getBestTrack, getQualityLabel } = require('./util'); +const { parseBitrate, parseSize, getQualityLabel } = require('./util'); +const { + createResolutionFilter, + createVideoQualityFilter, + createAudioLanguageFilter, + createSubtitleLanguageFilter, +} = require('./track'); const segmentsDto = (data = []) => { const mapSegment = (item) => ({ @@ -115,37 +121,10 @@ const parseManifest = (manifestString, manifestUri) => { videos, audios, subtitles, - withResolution({ width, height }) { - return videos.filter( - (track) => - (!width || track.resolution.width === width) && - (!height || track.resolution.height === height) - ); - }, - withVideoQuality(quality) { - const height = parseInt(quality); - const matchHeight = (track) => { - if (!height) return false; - const trackWidth = track.resolution.width; - const targetWidth = getWidth(height); - if (!trackWidth || !targetWidth) return false; - return trackWidth === targetWidth; - }; - const matches = videos.filter(matchHeight); - return matches.length ? matches : [getBestTrack(videos)]; - }, - withAudioLanguages(languages) { - if (!languages.length) return audios; - return audios.filter((track) => - languages.some((language) => track.language.startsWith(language)) - ); - }, - withSubtitleLanguages(languages) { - if (!languages.length) return subtitles; - return subtitles.filter((track) => - languages.some((language) => track.language.startsWith(language)) - ); - }, + withResolution: createResolutionFilter(videos), + withVideoQuality: createVideoQualityFilter(videos), + withAudioLanguages: createAudioLanguageFilter(audios), + withSubtitleLanguages: createSubtitleLanguageFilter(subtitles), }, }; diff --git a/lib/hls.js b/lib/hls.js index 83b4dec..ec9b9ab 100644 --- a/lib/hls.js +++ b/lib/hls.js @@ -2,6 +2,12 @@ const m3u8Parser = require('m3u8-parser'); const { parseBitrate, getQualityLabel } = require('./util'); +const { + createResolutionFilter, + createVideoQualityFilter, + createAudioLanguageFilter, + createSubtitleLanguageFilter, +} = require('./track'); const parseM3u8 = (manifestString) => { const parser = new m3u8Parser.Parser(); @@ -123,6 +129,10 @@ const parseManifest = async (manifestString, manifestUri) => { videos, audios, subtitles, + withResolution: createResolutionFilter(videos), + withVideoQuality: createVideoQualityFilter(videos), + withAudioLanguages: createAudioLanguageFilter(audios), + withSubtitleLanguages: createSubtitleLanguageFilter(subtitles), }, }; diff --git a/lib/track.js b/lib/track.js new file mode 100644 index 0000000..2bf6cb4 --- /dev/null +++ b/lib/track.js @@ -0,0 +1,49 @@ +const createResolutionFilter = (videos) => { + return ({ width, height }) => { + return videos.filter( + (track) => + (!width || track.resolution.width === width) && + (!height || track.resolution.height === height) + ); + }; +}; + +const createVideoQualityFilter = (videos) => { + return (quality) => { + const height = parseInt(quality); + const matchHeight = (track) => { + if (!height) return false; + const trackWidth = track.resolution.width; + const targetWidth = getWidth(height); + if (!trackWidth || !targetWidth) return false; + return trackWidth === targetWidth; + }; + const matches = videos.filter(matchHeight); + return matches.length ? matches : [getBestTrack(videos)]; + }; +}; + +const createAudioLanguageFilter = (audios) => { + return (languages) => { + if (!languages.length) return audios; + return audios.filter((track) => + languages.some((language) => track.language.startsWith(language)) + ); + }; +}; + +const createSubtitleLanguageFilter = (subtitles) => { + return (languages) => { + if (!languages.length) return subtitles; + return subtitles.filter((track) => + languages.some((language) => track.language.startsWith(language)) + ); + }; +}; + +module.exports = { + createResolutionFilter, + createVideoQualityFilter, + createAudioLanguageFilter, + createSubtitleLanguageFilter, +}; diff --git a/package.json b/package.json index 7b5cd49..6c170d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dasha", - "version": "3.0.0.alpha.4", + "version": "3.0.0.alpha.5", "author": "Vitaly Gashkov ", "description": "Parser for MPEG-DASH & HLS manifests", "license": "AGPL-3.0",