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
This commit is contained in:
claincly 2021-08-06 17:54:46 +01:00 committed by Oliver Woodman
parent d698e96a57
commit be19624a20
7 changed files with 61 additions and 15 deletions

View file

@ -162,8 +162,8 @@
format-related information.
([#9175](https://github.com/google/ExoPlayer/issues/9175)).
* SS:
* Propagate `StreamIndex` element `Name` attribute value as `Format`
label ([#9252](https://github.com/google/ExoPlayer/issues/9252)).
* Propagate `StreamIndex` element `Name` attribute value as `Format` label
([#9252](https://github.com/google/ExoPlayer/issues/9252)).
### 2.14.2 (2021-07-20)

View file

@ -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.RtspMessageUtil.RtspAuthUserInfo;
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.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@ -65,6 +67,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** The RTSP client. */
/* package */ final class RtspClient implements Closeable {
private static final String TAG = "RtspClient";
private static final long DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS = 30_000;
/** A listener for session information update. */
@ -100,6 +103,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final Uri uri;
@Nullable private final RtspAuthUserInfo rtspAuthUserInfo;
private final String userAgent;
private final boolean debugLoggingEnabled;
private final ArrayDeque<RtpLoadInfo> pendingSetupRtpLoadInfos;
// TODO(b/172331505) Add a timeout monitor for pending requests.
private final SparseArray<RtspRequest> pendingRequests;
@ -131,12 +135,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
SessionInfoListener sessionInfoListener,
PlaybackEventListener playbackEventListener,
String userAgent,
Uri uri) {
Uri uri,
boolean debugLoggingEnabled) {
this.sessionInfoListener = sessionInfoListener;
this.playbackEventListener = playbackEventListener;
this.uri = RtspMessageUtil.removeUserInfo(uri);
this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri);
this.userAgent = userAgent;
this.debugLoggingEnabled = debugLoggingEnabled;
pendingSetupRtpLoadInfos = new ArrayDeque<>();
pendingRequests = new SparseArray<>();
messageSender = new MessageSender();
@ -241,6 +247,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
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}. */
private static Socket getSocket(Uri uri) throws IOException {
checkArgument(uri.getHost() != null);
@ -396,7 +408,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int cSeq = Integer.parseInt(checkNotNull(request.headers.get(RtspHeaders.CSEQ)));
checkState(pendingRequests.get(cSeq) == null);
pendingRequests.append(cSeq, request);
messageChannel.send(RtspMessageUtil.serializeRequest(request));
List<String> message = RtspMessageUtil.serializeRequest(request);
maybeLogMessage(message);
messageChannel.send(message);
lastRequest = request;
}
}
@ -421,6 +435,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
private void handleRtspMessage(List<String> message) {
maybeLogMessage(message);
RtspResponse response = RtspMessageUtil.parseResponse(message);
int cSeq = Integer.parseInt(checkNotNull(response.headers.get(RtspHeaders.CSEQ)));

View file

@ -108,7 +108,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
RtpDataChannel.Factory rtpDataChannelFactory,
Uri uri,
Listener listener,
String userAgent) {
String userAgent,
boolean debugLoggingEnabled) {
this.allocator = allocator;
this.rtpDataChannelFactory = rtpDataChannelFactory;
this.listener = listener;
@ -120,7 +121,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* sessionInfoListener= */ internalListener,
/* playbackEventListener= */ internalListener,
/* userAgent= */ userAgent,
/* uri= */ uri);
/* uri= */ uri,
debugLoggingEnabled);
rtspLoaderWrappers = new ArrayList<>();
selectedLoadInfos = new ArrayList<>();

View file

@ -69,6 +69,7 @@ public final class RtspMediaSource extends BaseMediaSource {
private long timeoutMs;
private String userAgent;
private boolean forceUseRtpTcp;
private boolean debugLoggingEnabled;
public Factory() {
timeoutMs = DEFAULT_TIMEOUT_MS;
@ -102,6 +103,20 @@ public final class RtspMediaSource extends BaseMediaSource {
return this;
}
/**
* 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}.
*
@ -186,7 +201,8 @@ public final class RtspMediaSource extends BaseMediaSource {
forceUseRtpTcp
? new TransferRtpDataChannelFactory(timeoutMs)
: new UdpDataSourceRtpDataChannelFactory(timeoutMs),
userAgent);
userAgent,
debugLoggingEnabled);
}
}
@ -209,6 +225,7 @@ public final class RtspMediaSource extends BaseMediaSource {
private final RtpDataChannel.Factory rtpDataChannelFactory;
private final String userAgent;
private final Uri uri;
private final boolean debugLoggingEnabled;
private long timelineDurationUs;
private boolean timelineIsSeekable;
@ -217,11 +234,15 @@ public final class RtspMediaSource extends BaseMediaSource {
@VisibleForTesting
/* package */ RtspMediaSource(
MediaItem mediaItem, RtpDataChannel.Factory rtpDataChannelFactory, String userAgent) {
MediaItem mediaItem,
RtpDataChannel.Factory rtpDataChannelFactory,
String userAgent,
boolean debugLoggingEnabled) {
this.mediaItem = mediaItem;
this.rtpDataChannelFactory = rtpDataChannelFactory;
this.userAgent = userAgent;
this.uri = checkNotNull(this.mediaItem.playbackProperties).uri;
this.debugLoggingEnabled = debugLoggingEnabled;
this.timelineDurationUs = C.TIME_UNSET;
this.timelineIsPlaceholder = true;
}
@ -259,7 +280,8 @@ public final class RtspMediaSource extends BaseMediaSource {
timelineIsPlaceholder = false;
notifySourceInfoRefreshed();
},
userAgent);
userAgent,
debugLoggingEnabled);
}
@Override

View file

@ -112,7 +112,8 @@ public final class RtspClientTest {
},
EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()));
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null);
@ -153,7 +154,8 @@ public final class RtspClientTest {
},
EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()));
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> tracksInSession.get() != null);
@ -197,7 +199,8 @@ public final class RtspClientTest {
},
EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()));
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> failureMessage.get() != null);
@ -241,7 +244,8 @@ public final class RtspClientTest {
},
EMPTY_PLAYBACK_LISTENER,
/* userAgent= */ "ExoPlayer:RtspClientTest",
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()));
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* debugLoggingEnabled= */ false);
rtspClient.start();
RobolectricUtil.runMainLooperUntil(() -> failureCause.get() != null);

View file

@ -83,7 +83,8 @@ public final class RtspMediaPeriodTest {
new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS),
RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()),
/* listener= */ timing -> refreshedSourceDurationMs.set(timing.getDurationMs()),
/* userAgent= */ "ExoPlayer:RtspPeriodTest");
/* userAgent= */ "ExoPlayer:RtspPeriodTest",
/* debugLoggingEnabled= */ false);
mediaPeriod.prepare(
new MediaPeriod.Callback() {

View file

@ -157,7 +157,9 @@ public final class RtspPlaybackTest {
new RtspMediaSource(
MediaItem.fromUri(RtspTestUtils.getTestUri(serverRtspPortNumber)),
rtpDataChannelFactory,
"ExoPlayer:PlaybackTest"));
"ExoPlayer:PlaybackTest",
/* debugLoggingEnabled= */ false),
false);
return player;
}