Commit be19624a by claincly Committed by Oliver Woodman

Add a factory option to enable logging RTSP messages.

Many GH users find it hard to print out RTSP messages if they use ExoPlayer
as an external dependency.

PiperOrigin-RevId: 389197812
parent d698e96a
...@@ -162,8 +162,8 @@ ...@@ -162,8 +162,8 @@
format-related information. format-related information.
([#9175](https://github.com/google/ExoPlayer/issues/9175)). ([#9175](https://github.com/google/ExoPlayer/issues/9175)).
* SS: * SS:
* Propagate `StreamIndex` element `Name` attribute value as `Format` * Propagate `StreamIndex` element `Name` attribute value as `Format` label
label ([#9252](https://github.com/google/ExoPlayer/issues/9252)). ([#9252](https://github.com/google/ExoPlayer/issues/9252)).
### 2.14.2 (2021-07-20) ### 2.14.2 (2021-07-20)
......
...@@ -47,7 +47,9 @@ import com.google.android.exoplayer2.source.rtsp.RtspMediaSource.RtspPlaybackExc ...@@ -47,7 +47,9 @@ import com.google.android.exoplayer2.source.rtsp.RtspMediaSource.RtspPlaybackExc
import com.google.android.exoplayer2.source.rtsp.RtspMessageChannel.InterleavedBinaryDataListener; import com.google.android.exoplayer2.source.rtsp.RtspMessageChannel.InterleavedBinaryDataListener;
import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspAuthUserInfo; import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspAuthUserInfo;
import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspSessionHeader; import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspSessionHeader;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
...@@ -65,6 +67,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -65,6 +67,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** The RTSP client. */ /** The RTSP client. */
/* package */ final class RtspClient implements Closeable { /* package */ final class RtspClient implements Closeable {
private static final String TAG = "RtspClient";
private static final long DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS = 30_000; private static final long DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS = 30_000;
/** A listener for session information update. */ /** A listener for session information update. */
...@@ -100,6 +103,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -100,6 +103,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final Uri uri; private final Uri uri;
@Nullable private final RtspAuthUserInfo rtspAuthUserInfo; @Nullable private final RtspAuthUserInfo rtspAuthUserInfo;
private final String userAgent; private final String userAgent;
private final boolean debugLoggingEnabled;
private final ArrayDeque<RtpLoadInfo> pendingSetupRtpLoadInfos; private final ArrayDeque<RtpLoadInfo> pendingSetupRtpLoadInfos;
// TODO(b/172331505) Add a timeout monitor for pending requests. // TODO(b/172331505) Add a timeout monitor for pending requests.
private final SparseArray<RtspRequest> pendingRequests; private final SparseArray<RtspRequest> pendingRequests;
...@@ -131,12 +135,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -131,12 +135,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
SessionInfoListener sessionInfoListener, SessionInfoListener sessionInfoListener,
PlaybackEventListener playbackEventListener, PlaybackEventListener playbackEventListener,
String userAgent, String userAgent,
Uri uri) { Uri uri,
boolean debugLoggingEnabled) {
this.sessionInfoListener = sessionInfoListener; this.sessionInfoListener = sessionInfoListener;
this.playbackEventListener = playbackEventListener; this.playbackEventListener = playbackEventListener;
this.uri = RtspMessageUtil.removeUserInfo(uri); this.uri = RtspMessageUtil.removeUserInfo(uri);
this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri); this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri);
this.userAgent = userAgent; this.userAgent = userAgent;
this.debugLoggingEnabled = debugLoggingEnabled;
pendingSetupRtpLoadInfos = new ArrayDeque<>(); pendingSetupRtpLoadInfos = new ArrayDeque<>();
pendingRequests = new SparseArray<>(); pendingRequests = new SparseArray<>();
messageSender = new MessageSender(); messageSender = new MessageSender();
...@@ -241,6 +247,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -241,6 +247,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
messageSender.sendSetupRequest(loadInfo.getTrackUri(), loadInfo.getTransport(), sessionId); messageSender.sendSetupRequest(loadInfo.getTrackUri(), loadInfo.getTransport(), sessionId);
} }
private void maybeLogMessage(List<String> message) {
if (debugLoggingEnabled) {
Log.d(TAG, Joiner.on("\n").join(message));
}
}
/** Returns a {@link Socket} that is connected to the {@code uri}. */ /** Returns a {@link Socket} that is connected to the {@code uri}. */
private static Socket getSocket(Uri uri) throws IOException { private static Socket getSocket(Uri uri) throws IOException {
checkArgument(uri.getHost() != null); checkArgument(uri.getHost() != null);
...@@ -396,7 +408,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -396,7 +408,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int cSeq = Integer.parseInt(checkNotNull(request.headers.get(RtspHeaders.CSEQ))); int cSeq = Integer.parseInt(checkNotNull(request.headers.get(RtspHeaders.CSEQ)));
checkState(pendingRequests.get(cSeq) == null); checkState(pendingRequests.get(cSeq) == null);
pendingRequests.append(cSeq, request); pendingRequests.append(cSeq, request);
messageChannel.send(RtspMessageUtil.serializeRequest(request)); List<String> message = RtspMessageUtil.serializeRequest(request);
maybeLogMessage(message);
messageChannel.send(message);
lastRequest = request; lastRequest = request;
} }
} }
...@@ -421,6 +435,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -421,6 +435,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
private void handleRtspMessage(List<String> message) { private void handleRtspMessage(List<String> message) {
maybeLogMessage(message);
RtspResponse response = RtspMessageUtil.parseResponse(message); RtspResponse response = RtspMessageUtil.parseResponse(message);
int cSeq = Integer.parseInt(checkNotNull(response.headers.get(RtspHeaders.CSEQ))); int cSeq = Integer.parseInt(checkNotNull(response.headers.get(RtspHeaders.CSEQ)));
......
...@@ -108,7 +108,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -108,7 +108,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
RtpDataChannel.Factory rtpDataChannelFactory, RtpDataChannel.Factory rtpDataChannelFactory,
Uri uri, Uri uri,
Listener listener, Listener listener,
String userAgent) { String userAgent,
boolean debugLoggingEnabled) {
this.allocator = allocator; this.allocator = allocator;
this.rtpDataChannelFactory = rtpDataChannelFactory; this.rtpDataChannelFactory = rtpDataChannelFactory;
this.listener = listener; this.listener = listener;
...@@ -120,7 +121,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -120,7 +121,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* sessionInfoListener= */ internalListener, /* sessionInfoListener= */ internalListener,
/* playbackEventListener= */ internalListener, /* playbackEventListener= */ internalListener,
/* userAgent= */ userAgent, /* userAgent= */ userAgent,
/* uri= */ uri); /* uri= */ uri,
debugLoggingEnabled);
rtspLoaderWrappers = new ArrayList<>(); rtspLoaderWrappers = new ArrayList<>();
selectedLoadInfos = new ArrayList<>(); selectedLoadInfos = new ArrayList<>();
......
...@@ -69,6 +69,7 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -69,6 +69,7 @@ public final class RtspMediaSource extends BaseMediaSource {
private long timeoutMs; private long timeoutMs;
private String userAgent; private String userAgent;
private boolean forceUseRtpTcp; private boolean forceUseRtpTcp;
private boolean debugLoggingEnabled;
public Factory() { public Factory() {
timeoutMs = DEFAULT_TIMEOUT_MS; timeoutMs = DEFAULT_TIMEOUT_MS;
...@@ -103,6 +104,20 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -103,6 +104,20 @@ public final class RtspMediaSource extends BaseMediaSource {
} }
/** /**
* Sets whether to log RTSP messages, the default value is {@code false}.
*
* <p>This option presents a privacy risk, since it may expose sensitive information such as
* user's credentials.
*
* @param debugLoggingEnabled Whether to log RTSP messages.
* @return This Factory, for convenience.
*/
public Factory setDebugLoggingEnabled(boolean debugLoggingEnabled) {
this.debugLoggingEnabled = debugLoggingEnabled;
return this;
}
/**
* Sets the timeout in milliseconds, the default value is {@link #DEFAULT_TIMEOUT_MS}. * Sets the timeout in milliseconds, the default value is {@link #DEFAULT_TIMEOUT_MS}.
* *
* <p>A positive number of milliseconds to wait before lack of received RTP packets is treated * <p>A positive number of milliseconds to wait before lack of received RTP packets is treated
...@@ -186,7 +201,8 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -186,7 +201,8 @@ public final class RtspMediaSource extends BaseMediaSource {
forceUseRtpTcp forceUseRtpTcp
? new TransferRtpDataChannelFactory(timeoutMs) ? new TransferRtpDataChannelFactory(timeoutMs)
: new UdpDataSourceRtpDataChannelFactory(timeoutMs), : new UdpDataSourceRtpDataChannelFactory(timeoutMs),
userAgent); userAgent,
debugLoggingEnabled);
} }
} }
...@@ -209,6 +225,7 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -209,6 +225,7 @@ public final class RtspMediaSource extends BaseMediaSource {
private final RtpDataChannel.Factory rtpDataChannelFactory; private final RtpDataChannel.Factory rtpDataChannelFactory;
private final String userAgent; private final String userAgent;
private final Uri uri; private final Uri uri;
private final boolean debugLoggingEnabled;
private long timelineDurationUs; private long timelineDurationUs;
private boolean timelineIsSeekable; private boolean timelineIsSeekable;
...@@ -217,11 +234,15 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -217,11 +234,15 @@ public final class RtspMediaSource extends BaseMediaSource {
@VisibleForTesting @VisibleForTesting
/* package */ RtspMediaSource( /* package */ RtspMediaSource(
MediaItem mediaItem, RtpDataChannel.Factory rtpDataChannelFactory, String userAgent) { MediaItem mediaItem,
RtpDataChannel.Factory rtpDataChannelFactory,
String userAgent,
boolean debugLoggingEnabled) {
this.mediaItem = mediaItem; this.mediaItem = mediaItem;
this.rtpDataChannelFactory = rtpDataChannelFactory; this.rtpDataChannelFactory = rtpDataChannelFactory;
this.userAgent = userAgent; this.userAgent = userAgent;
this.uri = checkNotNull(this.mediaItem.playbackProperties).uri; this.uri = checkNotNull(this.mediaItem.playbackProperties).uri;
this.debugLoggingEnabled = debugLoggingEnabled;
this.timelineDurationUs = C.TIME_UNSET; this.timelineDurationUs = C.TIME_UNSET;
this.timelineIsPlaceholder = true; this.timelineIsPlaceholder = true;
} }
...@@ -259,7 +280,8 @@ public final class RtspMediaSource extends BaseMediaSource { ...@@ -259,7 +280,8 @@ public final class RtspMediaSource extends BaseMediaSource {
timelineIsPlaceholder = false; timelineIsPlaceholder = false;
notifySourceInfoRefreshed(); notifySourceInfoRefreshed();
}, },
userAgent); userAgent,
debugLoggingEnabled);
} }
@Override @Override
......
...@@ -112,7 +112,8 @@ public final class RtspClientTest { ...@@ -112,7 +112,8 @@ public final class RtspClientTest {
}, },
EMPTY_PLAYBACK_LISTENER, EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest", /* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start(); rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null); RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null);
...@@ -153,7 +154,8 @@ public final class RtspClientTest { ...@@ -153,7 +154,8 @@ public final class RtspClientTest {
}, },
EMPTY_PLAYBACK_LISTENER, EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest", /* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start(); rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null); RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null);
...@@ -197,7 +199,8 @@ public final class RtspClientTest { ...@@ -197,7 +199,8 @@ public final class RtspClientTest {
}, },
EMPTY_PLAYBACK_LISTENER, EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest", /* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start(); rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> failureMessage.get() != null); RobolectricUtil.runMainLooperUntil(() -> failureMessage.get() != null);
...@@ -241,7 +244,8 @@ public final class RtspClientTest { ...@@ -241,7 +244,8 @@ public final class RtspClientTest {
}, },
EMPTY_PLAYBACK_LISTENER, EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest", /* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber())); RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start(); rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> failureCause.get() != null); RobolectricUtil.runMainLooperUntil(() -> failureCause.get() != null);
......
...@@ -83,7 +83,8 @@ public final class RtspMediaPeriodTest { ...@@ -83,7 +83,8 @@ public final class RtspMediaPeriodTest {
new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS),
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* listener= */ timing -> refreshedSourceDurationMs.set(timing.getDurationMs()), /* listener= */ timing -> refreshedSourceDurationMs.set(timing.getDurationMs()),
/* userAgent= */ "ExoPlayer:RtspPeriodTest"); /* userAgent= */ "ExoPlayer:RtspPeriodTest",
/* debugLoggingEnabled= */ false);
mediaPeriod.prepare( mediaPeriod.prepare(
new MediaPeriod.Callback() { new MediaPeriod.Callback() {
......
...@@ -157,7 +157,9 @@ public final class RtspPlaybackTest { ...@@ -157,7 +157,9 @@ public final class RtspPlaybackTest {
new RtspMediaSource( new RtspMediaSource(
MediaItem.fromUri(RtspTestUtils.getTestUri(serverRtspPortNumber)), MediaItem.fromUri(RtspTestUtils.getTestUri(serverRtspPortNumber)),
rtpDataChannelFactory, rtpDataChannelFactory,
"ExoPlayer:PlaybackTest")); "ExoPlayer:PlaybackTest",
/* debugLoggingEnabled= */ false),
false);
return player; return player;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment