From aaac14de628576906a02e5aae41c142610e62dc4 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Fri, 18 Oct 2024 18:38:32 -0400 Subject: [PATCH] Support for auto-generated captions in Playlet backend --- CHANGELOG.md | 1 + .../Services/Innertube/InnertubeService.bs | 62 ++++++++++++++++++- .../VideoPlayer/VideoContentTask.bs | 7 ++- playlet-lib/src/source/utils/UrlUtils.bs | 10 ++- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 178426fe..4ddc6085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Spanish translations (Thanks to Kamborio) +- Support for auto-generated captions in Playlet backend ## [0.28.0] - 2024-10-13 diff --git a/playlet-lib/src/components/Services/Innertube/InnertubeService.bs b/playlet-lib/src/components/Services/Innertube/InnertubeService.bs index 54661566..7853ea25 100644 --- a/playlet-lib/src/components/Services/Innertube/InnertubeService.bs +++ b/playlet-lib/src/components/Services/Innertube/InnertubeService.bs @@ -246,7 +246,7 @@ namespace InnertubeService "hlsUrl": streamingData["hlsManifestUrl"] "adaptiveFormats": [] "formatStreams": [] - "captions": [] + "captions": ParseCaptions(payload) "recommendedVideos": [] } @@ -256,6 +256,66 @@ namespace InnertubeService } end function + function ParseCaptions(payload as object) as object + captions = payload["captions"] + if not IsAssociativeArray(captions) + return [] + end if + + playerCaptions = captions["playerCaptionsTracklistRenderer"] + if not IsAssociativeArray(playerCaptions) + return [] + end if + + tracks = playerCaptions["captionTracks"] + if not IsArray(tracks) + return [] + end if + + captions = [] + for each track in tracks + if not IsAssociativeArray(track) + continue for + end if + + baseUrl = track["baseUrl"] + if not IsString(baseUrl) + continue for + end if + + queryComponents = UrlUtils.ParseQueryComponents(baseUrl) + queryComponents["fmt"] = "vtt" + baseUrl = UrlUtils.SetQueryParams(baseUrl, queryComponents) + + languageCode = track["languageCode"] + if not IsString(languageCode) + continue for + end if + + label = "" + name = track["name"] + if IsAssociativeArray(name) + runs = name["runs"] + if IsArray(runs) + for each rn in runs + text = rn["text"] + if IsString(text) + label += text + end if + end for + end if + end if + + captions.Push({ + "label": label + "language_code": languageCode + "url": baseUrl + }) + end for + + return captions + end function + function ParseInnertubeNextResponse(payload as object, parsedResponse as object) as object if not parsedResponse.Success LogWarn("Invalid parsed response", parsedResponse) diff --git a/playlet-lib/src/components/VideoPlayer/VideoContentTask.bs b/playlet-lib/src/components/VideoPlayer/VideoContentTask.bs index ade0f321..7bd54c03 100644 --- a/playlet-lib/src/components/VideoPlayer/VideoContentTask.bs +++ b/playlet-lib/src/components/VideoPlayer/VideoContentTask.bs @@ -212,10 +212,15 @@ function SetCaptions(metadata as object, service as object, contentNode as objec code = isoLanguageList[code] end if + url = caption.url + if not url.StartsWith("http") + url = instance + url + end if + subtitleTracks.Push({ Description: caption.label Language: code - TrackName: instance + caption.url + TrackName: url }) end for diff --git a/playlet-lib/src/source/utils/UrlUtils.bs b/playlet-lib/src/source/utils/UrlUtils.bs index 3abf255c..d90b20ae 100644 --- a/playlet-lib/src/source/utils/UrlUtils.bs +++ b/playlet-lib/src/source/utils/UrlUtils.bs @@ -8,7 +8,7 @@ namespace UrlUtils function BuildUrl(url as string, pathParams as object, queryParams as object) as string url = SetPathParams(url, pathParams) - url = SetQueryParams(url, queryParams) + url = AppendQueryParams(url, queryParams) return url end function @@ -34,6 +34,14 @@ namespace UrlUtils end function function SetQueryParams(url as string, queryParams as object) as string + questionMarkIndex = url.InStr("?") + if questionMarkIndex <> -1 + url = url.Left(questionMarkIndex) + end if + return AppendQueryParams(url, queryParams) + end function + + function AppendQueryParams(url as string, queryParams as object) as string if queryParams = invalid or queryParams.Count() = 0 return url end if