Skip to content

Commit 606bb93

Browse files
authored
Merge pull request #1280 from FineFindus/feat/member-channeltab-info
2 parents ac500b6 + 9b98978 commit 606bb93

File tree

16 files changed

+1258
-0
lines changed

16 files changed

+1258
-0
lines changed

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamInfoItemExtractor.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
3636
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
3737
import org.schabi.newpipe.extractor.stream.StreamType;
38+
import org.schabi.newpipe.extractor.stream.ContentAvailability;
3839
import org.schabi.newpipe.extractor.utils.JsonUtils;
3940
import org.schabi.newpipe.extractor.utils.Parser;
4041
import 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
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
}

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff 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,

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff 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{"

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemExtractor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemsCollector.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/BaseSearchExtractorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/BaseStreamExtractorTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultSearchExtractorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff 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();

0 commit comments

Comments
 (0)