@@ -103,13 +103,17 @@ public OrfOnVideoInfoDTO deserialize(
103103 private Optional <Map <Qualities , String >> optimizeUrls (Optional <Map <Qualities , String >> urls ) {
104104 if (urls .isPresent () && urls .get ().size () == 1 ) {
105105 final Map <Qualities , String > urlMap = urls .get ();
106- final String urlToOptimize = urlMap .get (Qualities .NORMAL );
107- urlMap .put (Qualities .SMALL , urlToOptimize .replace ("QXA" , "Q4A" ));
108- urlMap .put (Qualities .NORMAL , urlToOptimize .replace ("QXA" , "Q6A" ));
109- urlMap .put (Qualities .HD , urlToOptimize .replace ("QXA" , "Q8C" ));
106+ String urlToOptimize = urlMap .get (Qualities .NORMAL );
107+ for (String s : List .of ("QXA" ,"QXB" )) {
108+ urlToOptimize = urlToOptimize .replace (s , "#Q#" );
109+ }
110+ urlMap .put (Qualities .SMALL , urlToOptimize .replace ("#Q#" , "Q4A" ));
111+ urlMap .put (Qualities .NORMAL , urlToOptimize .replace ("#Q#" , "Q6A" ));
112+ urlMap .put (Qualities .HD , urlToOptimize .replace ("#Q#" , "Q8C" ));
110113 }
111114 return urls ;
112115 }
116+
113117
114118 private Optional <String > buildOrResolveSubs (JsonElement jsonElement ) {
115119 Optional <String > subtitleSource = JsonUtils .getElementValueAsString (jsonElement , TAG_SUBTITLE );
@@ -185,7 +189,15 @@ private Optional<Map<Qualities, String>> parseVideoFromSources(JsonElement root)
185189 }
186190 }
187191 }
188- return parseVideoFromThumbnail (root );
192+ Optional <Map <Qualities , String >> fallbackThumbnail = parseVideoFromThumbnail (root );
193+ if (fallbackThumbnail .isPresent ()) {
194+ return fallbackThumbnail ;
195+ }
196+ Optional <Map <Qualities , String >> fallbackGapless = parseVideoFromGapless (root );
197+ if (fallbackGapless .isPresent ()) {
198+ return fallbackGapless ;
199+ }
200+ return Optional .empty ();
189201 }
190202
191203 private Optional <Map <Qualities , String >> parseVideoFromThumbnail (JsonElement root ) {
@@ -212,6 +224,28 @@ private Optional<Map<Qualities, String>> parseVideoFromThumbnail(JsonElement roo
212224 return Optional .of (urls );
213225 }
214226
227+ private Optional <Map <Qualities , String >> parseVideoFromGapless (JsonElement root ) {
228+ Map <Qualities , String > urls = new EnumMap <>(Qualities .class );
229+ try {
230+ Optional <JsonElement > gaplessSourceAT = JsonUtils .getElement (root , "gapless_sources_austria" , "hls" );
231+ if (gaplessSourceAT .isPresent ()) {
232+ gaplessSourceAT .get ().getAsJsonArray ().forEach ( e -> {
233+ Optional <String > url = JsonUtils .getElementValueAsString (e , "src" );
234+ Optional <String > drm = JsonUtils .getElementValueAsString (e , "is_drm_protected" );
235+ if (url .isPresent () && drm .orElse ("" ).equalsIgnoreCase ("false" )) {
236+ urls .put (Qualities .NORMAL , url .get ());
237+ }
238+ });
239+ }
240+ } catch (Exception e ) {
241+ LOG .error ("generateFallbackVideo {}" , e );
242+ }
243+ if (urls .size () == 0 ) {
244+ return Optional .empty ();
245+ }
246+ return Optional .of (urls );
247+ }
248+
215249 private Optional <Map <Qualities , String >> readVideoForTargetCodec (JsonElement urlArray , String targetCodec ) {
216250 Map <Qualities , String > urls = new EnumMap <>(Qualities .class );
217251 for (JsonElement videoElement : urlArray .getAsJsonArray ()) {
0 commit comments