Skip to content

Commit 3e3aa9e

Browse files
Add LoggingHttpDataSource to log http requests sent by ExoPlayer for non YouTube streams
1 parent b9c5a79 commit 3e3aa9e

3 files changed

Lines changed: 140 additions & 13 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.schabi.newpipe.player.datasource;
2+
3+
import android.util.Log;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.annotation.Nullable;
7+
8+
import com.google.android.exoplayer2.upstream.DataSpec;
9+
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
10+
import com.google.android.exoplayer2.upstream.HttpDataSource;
11+
import com.google.android.exoplayer2.upstream.TransferListener;
12+
13+
import org.schabi.newpipe.DownloaderImpl;
14+
15+
import java.nio.charset.StandardCharsets;
16+
import java.util.Map;
17+
18+
public class LoggingHttpDataSource extends DefaultHttpDataSource {
19+
20+
public final String TAG = getClass().getSimpleName() + "@" + hashCode();
21+
22+
public LoggingHttpDataSource() { }
23+
24+
public LoggingHttpDataSource(@Nullable final String userAgent,
25+
final int connectTimeoutMillis,
26+
final int readTimeoutMillis,
27+
final boolean allowCrossProtocolRedirects,
28+
@Nullable final RequestProperties defaultRequestProperties) {
29+
super(userAgent,
30+
connectTimeoutMillis,
31+
readTimeoutMillis,
32+
allowCrossProtocolRedirects,
33+
defaultRequestProperties);
34+
}
35+
36+
37+
@Override
38+
public long open(final DataSpec dataSpec) throws HttpDataSourceException {
39+
Log.d(TAG, "Request URL: " + dataSpec.uri);
40+
try {
41+
return super.open(dataSpec);
42+
} catch (final HttpDataSource.InvalidResponseCodeException e) {
43+
Log.e(TAG, "HTTP error for URL: " + dataSpec.uri);
44+
Log.e(TAG, "Response code: " + e.responseCode);
45+
Log.e(TAG, "Headers: " + e.headerFields);
46+
Log.e(TAG, "Body: " + new String(e.responseBody, StandardCharsets.UTF_8));
47+
throw e;
48+
}
49+
}
50+
51+
@SuppressWarnings("checkstyle:hiddenField")
52+
public static class Factory implements HttpDataSource.Factory {
53+
54+
final RequestProperties defaultRequestProperties;
55+
56+
@Nullable
57+
TransferListener transferListener;
58+
@Nullable
59+
String userAgent;
60+
int connectTimeoutMs;
61+
int readTimeoutMs;
62+
boolean allowCrossProtocolRedirects;
63+
64+
public Factory() {
65+
defaultRequestProperties = new RequestProperties();
66+
connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MILLIS;
67+
readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLIS;
68+
userAgent = DownloaderImpl.USER_AGENT;
69+
}
70+
71+
@NonNull
72+
@Override
73+
public HttpDataSource createDataSource() {
74+
final var dataSource = new LoggingHttpDataSource(userAgent,
75+
connectTimeoutMs,
76+
readTimeoutMs,
77+
allowCrossProtocolRedirects,
78+
defaultRequestProperties);
79+
if (transferListener != null) {
80+
dataSource.addTransferListener(transferListener);
81+
}
82+
return dataSource;
83+
}
84+
85+
@NonNull
86+
@Override
87+
public Factory setDefaultRequestProperties(
88+
@NonNull final Map<String, String> defaultRequestProperties) {
89+
this.defaultRequestProperties.clearAndSet(defaultRequestProperties);
90+
return this;
91+
}
92+
93+
public Factory setUserAgent(@Nullable final String userAgent) {
94+
this.userAgent = userAgent;
95+
return this;
96+
}
97+
98+
public Factory setConnectTimeoutMs(final int connectTimeoutMs) {
99+
this.connectTimeoutMs = connectTimeoutMs;
100+
return this;
101+
}
102+
103+
public Factory setReadTimeoutMs(final int readTimeoutMs) {
104+
this.readTimeoutMs = readTimeoutMs;
105+
return this;
106+
}
107+
108+
public Factory setAllowCrossProtocolRedirects(final boolean allowCrossProtocolRedirects) {
109+
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
110+
return this;
111+
}
112+
113+
public Factory setTransferListener(@Nullable final TransferListener transferListener) {
114+
this.transferListener = transferListener;
115+
return this;
116+
}
117+
}
118+
}

app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import android.content.Context;
66
import android.util.Log;
77

8-
import androidx.annotation.Nullable;
8+
import androidx.annotation.NonNull;
99

1010
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider;
1111
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
@@ -18,15 +18,15 @@
1818
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
1919
import com.google.android.exoplayer2.upstream.DataSource;
2020
import com.google.android.exoplayer2.upstream.DefaultDataSource;
21-
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
2221
import com.google.android.exoplayer2.upstream.TransferListener;
2322
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
2423
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
2524

26-
import org.schabi.newpipe.DownloaderImpl;
25+
import org.jetbrains.annotations.Contract;
2726
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubeOtfDashManifestCreator;
2827
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubePostLiveStreamDvrDashManifestCreator;
2928
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubeProgressiveDashManifestCreator;
29+
import org.schabi.newpipe.player.datasource.LoggingHttpDataSource;
3030
import org.schabi.newpipe.player.datasource.NonUriHlsDataSourceFactory;
3131
import org.schabi.newpipe.player.datasource.YoutubeHttpDataSource;
3232

@@ -78,27 +78,32 @@ public class PlayerDataSource {
7878
private final CacheFactory ytProgressiveDashCacheDataSourceFactory;
7979

8080

81+
private final Context context;
82+
private final TransferListener transferListener;
83+
84+
8185
public PlayerDataSource(final Context context,
8286
final TransferListener transferListener) {
83-
87+
this.context = context;
88+
this.transferListener = transferListener;
8489
progressiveLoadIntervalBytes = PlayerHelper.getProgressiveLoadIntervalBytes(context);
8590

8691
// make sure the static cache was created: needed by CacheFactories below
8792
instantiateCacheIfNeeded(context);
8893

89-
// generic data source factories use DefaultHttpDataSource.Factory
94+
// generic data source factories use LoggingHttpDataSource.Factory, which is a wrapper
95+
// around DefaultHttpDataSource
9096
cachelessDataSourceFactory = new DefaultDataSource.Factory(context,
91-
new DefaultHttpDataSource.Factory().setUserAgent(DownloaderImpl.USER_AGENT))
97+
new LoggingHttpDataSource.Factory())
9298
.setTransferListener(transferListener);
93-
cacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
94-
new DefaultHttpDataSource.Factory().setUserAgent(DownloaderImpl.USER_AGENT));
99+
cacheDataSourceFactory = createCacheDataSourceFactory(new LoggingHttpDataSource.Factory());
95100

96101
// YouTube-specific data source factories use getYoutubeHttpDataSourceFactory()
97-
ytHlsCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
102+
ytHlsCacheDataSourceFactory = createCacheDataSourceFactory(
98103
getYoutubeHttpDataSourceFactory(false, false));
99-
ytDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
104+
ytDashCacheDataSourceFactory = createCacheDataSourceFactory(
100105
getYoutubeHttpDataSourceFactory(true, true));
101-
ytProgressiveDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
106+
ytProgressiveDashCacheDataSourceFactory = createCacheDataSourceFactory(
102107
getYoutubeHttpDataSourceFactory(false, true));
103108

104109
// set the maximum size to manifest creators
@@ -108,6 +113,11 @@ public PlayerDataSource(final Context context,
108113
MAX_MANIFEST_CACHE_SIZE);
109114
}
110115

116+
@NonNull
117+
@Contract(value = "_ -> new", pure = true)
118+
private CacheFactory createCacheDataSourceFactory(final DataSource.Factory wrappedFactory) {
119+
return new CacheFactory(context, transferListener, cache, wrappedFactory);
120+
}
111121

112122
//region Live media source factories
113123
public SsMediaSource.Factory getLiveSsMediaSourceFactory() {

app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,7 @@ private static HlsMediaSource buildHlsMediaSource(final PlayerDataSource dataSou
343343
.build());
344344
}
345345

346-
final NonUriHlsDataSourceFactory.Builder hlsDataSourceFactoryBuilder =
347-
new NonUriHlsDataSourceFactory.Builder();
346+
final var hlsDataSourceFactoryBuilder = new NonUriHlsDataSourceFactory.Builder();
348347
hlsDataSourceFactoryBuilder.setPlaylistString(stream.getContent());
349348

350349
return dataSource.getHlsMediaSourceFactory(hlsDataSourceFactoryBuilder)

0 commit comments

Comments
 (0)