Skip to content

Commit 0fadb57

Browse files
committed
[duplicated subtitle][YouTube] Introduce AppStreamInfo to normalize subtitles in app layer.
Introduce a new domain class `AppStreamInfo` to perform subtitle normalization (deduplication) on the application side without modifying the extractor data `StreamInfo`. Previously subtitle deduplication logic modified `StreamInfo` directly, which mixes application concerns with extractor data structures. This change separates responsibilities by projecting extractor `StreamInfo` into an app-level domain object. Key points: - Preserve original `StreamInfo` from the extractor unchanged - Perform subtitle deduplication once when constructing `AppStreamInfo` - Provide normalized subtitle list for player and download usage - Ensure subtitle normalization logic is centralized and reusable - `from()` only perform object creation - subtitle deduplication (which requires network downloading) is in the loadNormalizedSubtitles().
1 parent 007c501 commit 0fadb57

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package org.schabi.newpipe.streams;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
6+
import android.util.Log;
7+
8+
import org.schabi.newpipe.extractor.stream.StreamInfo;
9+
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
10+
import org.schabi.newpipe.extractor.MediaFormat;
11+
import org.schabi.newpipe.util.subtitle.SubtitleDeduplicator;
12+
import org.schabi.newpipe.util.subtitle.SubtitleOrigin;
13+
14+
import java.util.ArrayList;
15+
import java.util.Collections;
16+
import java.util.List;
17+
18+
public final class AppStreamInfo {
19+
private static final String TAG = AppStreamInfo.class.getSimpleName();
20+
21+
@NonNull
22+
private final StreamInfo originalStreamInfo;
23+
@Nullable
24+
private List<SubtitlesStream> normalizedSubtitles = null;
25+
26+
private AppStreamInfo(@NonNull final StreamInfo original) {
27+
this.originalStreamInfo = original;
28+
}
29+
30+
// Factory method: build AppStreamInfo from raw StreamInfo.
31+
@NonNull
32+
public static AppStreamInfo from(@NonNull final StreamInfo info) {
33+
return new AppStreamInfo(info);
34+
}
35+
36+
@NonNull
37+
public StreamInfo getOriginal() {
38+
return originalStreamInfo;
39+
}
40+
41+
@NonNull
42+
public List<SubtitlesStream> loadNormalizedSubtitles() {
43+
if (null == normalizedSubtitles) {
44+
final List<SubtitlesStream> originalSubtitles =
45+
originalStreamInfo.getSubtitles();
46+
47+
normalizedSubtitles =
48+
deduplicateSubtitles(originalSubtitles);
49+
}
50+
51+
return normalizedSubtitles;
52+
}
53+
54+
@NonNull
55+
private static List<SubtitlesStream> deduplicateSubtitles(
56+
@Nullable final List<SubtitlesStream> originalSubtitles) {
57+
58+
if ((null == originalSubtitles) || originalSubtitles.isEmpty()) {
59+
return Collections.emptyList();
60+
}
61+
62+
final List<SubtitlesStream> newSubtitles = new ArrayList<>();
63+
64+
for (final SubtitlesStream oldSubtitle : originalSubtitles) {
65+
final MediaFormat format = oldSubtitle.getFormat();
66+
if (null == format) {
67+
newSubtitles.add(oldSubtitle);
68+
continue;
69+
}
70+
71+
try {
72+
final SubtitleOrigin origin =
73+
SubtitleDeduplicator.getSubtitleOrigin(
74+
oldSubtitle.isAutoGenerated(),
75+
false
76+
);
77+
78+
final String remoteSubtitleUrl = oldSubtitle.getContent();
79+
80+
final String subtitleUrl =
81+
SubtitleDeduplicator.checkAndDeduplicate(
82+
remoteSubtitleUrl,
83+
format,
84+
origin
85+
);
86+
87+
if (remoteSubtitleUrl.equals(subtitleUrl)) {
88+
newSubtitles.add(oldSubtitle);
89+
} else {
90+
final SubtitlesStream oneNewSubtitle =
91+
new SubtitlesStream.Builder()
92+
.setContent(subtitleUrl, true)
93+
.setMediaFormat(format)
94+
.setLanguageCode(oldSubtitle.getLanguageTag())
95+
.setAutoGenerated(oldSubtitle.isAutoGenerated())
96+
.build();
97+
98+
newSubtitles.add(oneNewSubtitle);
99+
}
100+
} catch (final Exception e) {
101+
Log.w(TAG, "Subtitle deduplication failed", e);
102+
newSubtitles.add(oldSubtitle);
103+
}
104+
}
105+
106+
return newSubtitles;
107+
}
108+
109+
}

0 commit comments

Comments
 (0)