File tree Expand file tree Collapse file tree 16 files changed +1258
-0
lines changed Expand file tree Collapse file tree 16 files changed +1258
-0
lines changed Original file line number Diff line number Diff line change 3535import org .schabi .newpipe .extractor .services .youtube .linkHandler .YoutubeStreamLinkHandlerFactory ;
3636import org .schabi .newpipe .extractor .stream .StreamInfoItemExtractor ;
3737import org .schabi .newpipe .extractor .stream .StreamType ;
38+ import org .schabi .newpipe .extractor .stream .ContentAvailability ;
3839import org .schabi .newpipe .extractor .utils .JsonUtils ;
3940import org .schabi .newpipe .extractor .utils .Parser ;
4041import org .schabi .newpipe .extractor .utils .Utils ;
@@ -470,4 +471,33 @@ public boolean isShortFormContent() throws ParsingException {
470471 throw new ParsingException ("Could not determine if this is short-form content" , e );
471472 }
472473 }
474+
475+ private boolean isMembersOnly () throws ParsingException {
476+ return videoInfo .getArray ("badges" )
477+ .stream ()
478+ .filter (JsonObject .class ::isInstance )
479+ .map (JsonObject .class ::cast )
480+ .map (badge -> badge .getObject ("metadataBadgeRenderer" ).getString ("style" ))
481+ .anyMatch ("BADGE_STYLE_TYPE_MEMBERS_ONLY" ::equals );
482+ }
483+
484+
485+ @ Nonnull
486+ @ Override
487+ public ContentAvailability getContentAvailability () throws ParsingException {
488+ if (isPremiere ()) {
489+ return ContentAvailability .UPCOMING ;
490+ }
491+
492+ if (isMembersOnly ()) {
493+ return ContentAvailability .MEMBERSHIP ;
494+ }
495+
496+ if (isPremium ()) {
497+ return ContentAvailability .PAID ;
498+ }
499+
500+ return ContentAvailability .AVAILABLE ;
501+ }
502+
473503}
Original file line number Diff line number Diff line change 1+ /*
2+ * Created by FineFindus on 10.07.25.
3+ *
4+ * Copyright (C) 2025 FineFindus <[email protected] > 5+ * ContentAvailability.java is part of NewPipe Extractor.
6+ *
7+ * NewPipe Extractor is free software: you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation, either version 3 of the License, or
10+ * (at your option) any later version.
11+ *
12+ * NewPipe Extractor is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
19+ */
20+ package org .schabi .newpipe .extractor .stream ;
21+
22+ /**
23+ * Availability of the stream.
24+ *
25+ * <p>A stream may be available to all, restricted to a certain user group or time.</p>
26+ */
27+ public enum ContentAvailability {
28+ /**
29+ * The availability of the stream is unknown (but clients may assume that it's available).
30+ */
31+ UNKNOWN ,
32+ /**
33+ * The stream is available to all users.
34+ */
35+ AVAILABLE ,
36+ /**
37+ * The stream is available to users with a membership.
38+ */
39+ MEMBERSHIP ,
40+ /**
41+ * The stream is behind a paywall.
42+ */
43+ PAID ,
44+ /**
45+ * The stream is only available in the future.
46+ */
47+ UPCOMING ,
48+ }
Original file line number Diff line number Diff line change @@ -581,6 +581,17 @@ public boolean isShortFormContent() throws ParsingException {
581581 return false ;
582582 }
583583
584+ /**
585+ * Get the availability of the stream.
586+ *
587+ * @return The stream's availability
588+ * @throws ParsingException if there is an error in the extraction
589+ */
590+ @ Nonnull
591+ public ContentAvailability getContentAvailability () throws ParsingException {
592+ return ContentAvailability .UNKNOWN ;
593+ }
594+
584595 public enum Privacy {
585596 PUBLIC ,
586597 UNLISTED ,
Original file line number Diff line number Diff line change @@ -330,6 +330,11 @@ private static void extractOptionalData(final StreamInfo streamInfo,
330330 } catch (final Exception e ) {
331331 streamInfo .addError (e );
332332 }
333+ try {
334+ streamInfo .setContentAvailability (extractor .getContentAvailability ());
335+ } catch (final Exception e ) {
336+ streamInfo .addError (e );
337+ }
333338
334339 streamInfo .setRelatedItems (ExtractorHelper .getRelatedItemsOrLogError (streamInfo ,
335340 extractor ));
@@ -381,6 +386,8 @@ private static void extractOptionalData(final StreamInfo streamInfo,
381386 private List <StreamSegment > streamSegments = List .of ();
382387 private List <MetaInfo > metaInfo = List .of ();
383388 private boolean shortFormContent = false ;
389+ @ Nonnull
390+ private ContentAvailability contentAvailability = ContentAvailability .AVAILABLE ;
384391
385392 /**
386393 * Preview frames, e.g. for the storyboard / seekbar thumbnail preview
@@ -727,4 +734,13 @@ public boolean isShortFormContent() {
727734 public void setShortFormContent (final boolean isShortFormContent ) {
728735 this .shortFormContent = isShortFormContent ;
729736 }
737+
738+ @ Nonnull
739+ public ContentAvailability getContentAvailability () {
740+ return contentAvailability ;
741+ }
742+
743+ public void setContentAvailability (@ Nonnull final ContentAvailability availability ) {
744+ this .contentAvailability = availability ;
745+ }
730746}
Original file line number Diff line number Diff line change @@ -47,6 +47,8 @@ public class StreamInfoItem extends InfoItem {
4747 private List <Image > uploaderAvatars = List .of ();
4848 private boolean uploaderVerified = false ;
4949 private boolean shortFormContent = false ;
50+ @ Nonnull
51+ private ContentAvailability contentAvailability = ContentAvailability .AVAILABLE ;
5052
5153 public StreamInfoItem (final int serviceId ,
5254 final String url ,
@@ -143,6 +145,23 @@ public void setShortFormContent(final boolean shortFormContent) {
143145 this .shortFormContent = shortFormContent ;
144146 }
145147
148+ /**
149+ * Gets the availability of the content.
150+ *
151+ * @return The availability of the stream.
152+ */
153+ @ Nonnull
154+ public ContentAvailability getContentAvailability () {
155+ return contentAvailability ;
156+ }
157+
158+ /**
159+ * Sets the availability of the Stream.
160+ */
161+ public void setContentAvailability (@ Nonnull final ContentAvailability availability ) {
162+ this .contentAvailability = availability ;
163+ }
164+
146165 @ Override
147166 public String toString () {
148167 return "StreamInfoItem{"
Original file line number Diff line number Diff line change @@ -147,4 +147,19 @@ default String getShortDescription() throws ParsingException {
147147 default boolean isShortFormContent () throws ParsingException {
148148 return false ;
149149 }
150+
151+ /**
152+ * Get the availability of the stream.
153+ *
154+ * <p>
155+ * The availability may not reflect the actual availability when requesting the stream.
156+ * </p>
157+ *
158+ * @return The stream's availability
159+ * @throws ParsingException if there is an error in the extraction
160+ */
161+ @ Nonnull
162+ default ContentAvailability getContentAvailability () throws ParsingException {
163+ return ContentAvailability .UNKNOWN ;
164+ }
150165}
Original file line number Diff line number Diff line change @@ -103,6 +103,11 @@ public StreamInfoItem extract(final StreamInfoItemExtractor extractor) throws Pa
103103 } catch (final Exception e ) {
104104 addError (e );
105105 }
106+ try {
107+ resultItem .setContentAvailability (extractor .getContentAvailability ());
108+ } catch (final Exception e ) {
109+ addError (e );
110+ }
106111
107112 return resultItem ;
108113 }
Original file line number Diff line number Diff line change @@ -9,4 +9,6 @@ public interface BaseSearchExtractorTest extends BaseListExtractorTest {
99 void testSearchSuggestion () throws Exception ;
1010 @ Test
1111 void testSearchCorrected () throws Exception ;
12+ @ Test
13+ void testMetaInfo () throws Exception ;
1214}
Original file line number Diff line number Diff line change @@ -68,4 +68,10 @@ public interface BaseStreamExtractorTest extends BaseExtractorTest {
6868 void testTags () throws Exception ;
6969 @ Test
7070 void testSupportInfo () throws Exception ;
71+ @ Test
72+ void testStreamSegmentsCount () throws Exception ;
73+ @ Test
74+ void testMetaInfo () throws Exception ;
75+ @ Test
76+ void testContentAvailability () throws Exception ;
7177}
Original file line number Diff line number Diff line change @@ -50,6 +50,7 @@ public void testSearchSuggestion() throws Exception {
5050 }
5151
5252 @ Test
53+ @ Override
5354 public void testSearchCorrected () throws Exception {
5455 assertEquals (isCorrectedSearch (), extractor ().isCorrectedSearch ());
5556 }
@@ -58,6 +59,7 @@ public void testSearchCorrected() throws Exception {
5859 * @see DefaultStreamExtractorTest#testMetaInfo()
5960 */
6061 @ Test
62+ @ Override
6163 public void testMetaInfo () throws Exception {
6264 final List <MetaInfo > metaInfoList = extractor ().getMetaInfo ();
6365 final List <MetaInfo > expectedMetaInfoList = expectedMetaInfo ();
You can’t perform that action at this time.
0 commit comments