Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ff7dcbd6
authored
Sep 13, 2021
by
claincly
Committed by
Christos Tsilopoulos
Sep 14, 2021
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Handle RTSP 301/302 redirection.
PiperOrigin-RevId: 396303242
parent
76014cf0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
9 deletions
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspHeaders.java
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMessageUtil.java
library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspClient.java
View file @
ff7dcbd6
...
...
@@ -101,8 +101,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private
final
SessionInfoListener
sessionInfoListener
;
private
final
PlaybackEventListener
playbackEventListener
;
private
final
Uri
uri
;
@Nullable
private
final
RtspAuthUserInfo
rtspAuthUserInfo
;
private
final
String
userAgent
;
private
final
boolean
debugLoggingEnabled
;
private
final
ArrayDeque
<
RtpLoadInfo
>
pendingSetupRtpLoadInfos
;
...
...
@@ -110,7 +108,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private
final
SparseArray
<
RtspRequest
>
pendingRequests
;
private
final
MessageSender
messageSender
;
/** RTSP session URI. */
private
Uri
uri
;
private
RtspMessageChannel
messageChannel
;
@Nullable
private
RtspAuthUserInfo
rtspAuthUserInfo
;
@Nullable
private
String
sessionId
;
@Nullable
private
KeepAliveMonitor
keepAliveMonitor
;
@Nullable
private
RtspAuthenticationInfo
rtspAuthenticationInfo
;
...
...
@@ -140,15 +142,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
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
();
pendingSeekPositionUs
=
C
.
TIME_UNSET
;
messageChannel
=
new
RtspMessageChannel
(
new
MessageListener
());
this
.
pendingSetupRtpLoadInfos
=
new
ArrayDeque
<>();
this
.
pendingRequests
=
new
SparseArray
<>();
this
.
messageSender
=
new
MessageSender
();
this
.
uri
=
RtspMessageUtil
.
removeUserInfo
(
uri
);
this
.
messageChannel
=
new
RtspMessageChannel
(
new
MessageListener
());
this
.
rtspAuthUserInfo
=
RtspMessageUtil
.
parseUserInfo
(
uri
);
this
.
pendingSeekPositionUs
=
C
.
TIME_UNSET
;
}
/**
...
...
@@ -482,6 +484,20 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
switch
(
response
.
status
)
{
case
200
:
break
;
case
301
:
case
302
:
// Redirection request.
@Nullable
String
redirectionUriString
=
response
.
headers
.
get
(
RtspHeaders
.
LOCATION
);
if
(
redirectionUriString
==
null
)
{
sessionInfoListener
.
onSessionTimelineRequestFailed
(
"Redirection without new location."
,
/* cause= */
null
);
}
else
{
Uri
redirectionUri
=
Uri
.
parse
(
redirectionUriString
);
RtspClient
.
this
.
uri
=
RtspMessageUtil
.
removeUserInfo
(
redirectionUri
);
RtspClient
.
this
.
rtspAuthUserInfo
=
RtspMessageUtil
.
parseUserInfo
(
redirectionUri
);
messageSender
.
sendDescribeRequest
(
RtspClient
.
this
.
uri
,
RtspClient
.
this
.
sessionId
);
}
return
;
case
401
:
if
(
rtspAuthUserInfo
!=
null
&&
!
receivedAuthorizationRequest
)
{
// Unauthorized.
...
...
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspHeaders.java
View file @
ff7dcbd6
...
...
@@ -50,6 +50,7 @@ import java.util.Map;
public
static
final
String
CSEQ
=
"CSeq"
;
public
static
final
String
DATE
=
"Date"
;
public
static
final
String
EXPIRES
=
"Expires"
;
public
static
final
String
LOCATION
=
"Location"
;
public
static
final
String
PROXY_AUTHENTICATE
=
"Proxy-Authenticate"
;
public
static
final
String
PROXY_REQUIRE
=
"Proxy-Require"
;
public
static
final
String
PUBLIC
=
"Public"
;
...
...
@@ -251,6 +252,8 @@ import java.util.Map;
return
DATE
;
}
else
if
(
Ascii
.
equalsIgnoreCase
(
messageHeaderName
,
EXPIRES
))
{
return
EXPIRES
;
}
else
if
(
Ascii
.
equalsIgnoreCase
(
messageHeaderName
,
LOCATION
))
{
return
LOCATION
;
}
else
if
(
Ascii
.
equalsIgnoreCase
(
messageHeaderName
,
PROXY_AUTHENTICATE
))
{
return
PROXY_AUTHENTICATE
;
}
else
if
(
Ascii
.
equalsIgnoreCase
(
messageHeaderName
,
PROXY_REQUIRE
))
{
...
...
library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMessageUtil.java
View file @
ff7dcbd6
...
...
@@ -462,6 +462,10 @@ import java.util.regex.Pattern;
switch
(
statusCode
)
{
case
200
:
return
"OK"
;
case
301
:
return
"Move Permanently"
;
case
302
:
return
"Move Temporarily"
;
case
400
:
return
"Bad Request"
;
case
401
:
...
...
library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspClientTest.java
View file @
ff7dcbd6
...
...
@@ -121,6 +121,56 @@ public final class RtspClientTest {
}
@Test
public
void
connectServerAndClient_describeRedirects_updatesSessionTimeline
()
throws
Exception
{
class
ResponseProvider
implements
RtspServer
.
ResponseProvider
{
@Override
public
RtspResponse
getOptionsResponse
()
{
return
new
RtspResponse
(
/* status= */
200
,
RtspHeaders
.
EMPTY
);
}
@Override
public
RtspResponse
getDescribeResponse
(
Uri
requestedUri
)
{
if
(!
requestedUri
.
getPath
().
contains
(
"redirect"
))
{
return
new
RtspResponse
(
301
,
new
RtspHeaders
.
Builder
()
.
add
(
RtspHeaders
.
LOCATION
,
requestedUri
.
buildUpon
().
appendEncodedPath
(
"redirect"
).
build
().
toString
())
.
build
());
}
return
RtspTestUtils
.
newDescribeResponseWithSdpMessage
(
SESSION_DESCRIPTION
,
rtpPacketStreamDumps
,
requestedUri
);
}
}
rtspServer
=
new
RtspServer
(
new
ResponseProvider
());
AtomicReference
<
ImmutableList
<
RtspMediaTrack
>>
tracksInSession
=
new
AtomicReference
<>();
rtspClient
=
new
RtspClient
(
new
SessionInfoListener
()
{
@Override
public
void
onSessionTimelineUpdated
(
RtspSessionTiming
timing
,
ImmutableList
<
RtspMediaTrack
>
tracks
)
{
tracksInSession
.
set
(
tracks
);
}
@Override
public
void
onSessionTimelineRequestFailed
(
String
message
,
@Nullable
Throwable
cause
)
{}
},
EMPTY_PLAYBACK_LISTENER
,
/* userAgent= */
"ExoPlayer:RtspClientTest"
,
RtspTestUtils
.
getTestUri
(
rtspServer
.
startAndGetPortNumber
()),
/* debugLoggingEnabled= */
false
);
rtspClient
.
start
();
RobolectricUtil
.
runMainLooperUntil
(()
->
tracksInSession
.
get
()
!=
null
);
assertThat
(
tracksInSession
.
get
()).
hasSize
(
2
);
}
@Test
public
void
connectServerAndClient_serverSupportsDescribeNoHeaderInOptions_updatesSessionTimeline
()
throws
Exception
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment