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
1c7c6fb9
authored
Aug 11, 2020
by
olly
Committed by
Oliver Woodman
Aug 19, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Increase flexibility of ISM URL handling
PiperOrigin-RevId: 326025335
parent
590e81e5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
56 additions
and
43 deletions
RELEASENOTES.md
library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java
library/core/src/main/java/com/google/android/exoplayer2/util/Util.java
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsUtil.java
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java
RELEASENOTES.md
View file @
1c7c6fb9
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
boxes.
boxes.
*
FLV: Ignore
`SCRIPTDATA`
segments with invalid name types, rather than
*
FLV: Ignore
`SCRIPTDATA`
segments with invalid name types, rather than
failing playback (
[
#7675
](
https://github.com/google/ExoPlayer/issues/7675
)
).
failing playback (
[
#7675
](
https://github.com/google/ExoPlayer/issues/7675
)
).
*
Better infer content type for
`.ism`
and
`.isml`
streaming URLs.
*
Workaround an issue on Broadcom based devices where playbacks would not
*
Workaround an issue on Broadcom based devices where playbacks would not
transition to
`STATE_ENDED`
when using video tunneling mode
transition to
`STATE_ENDED`
when using video tunneling mode
(
[
#7647
](
https://github.com/google/ExoPlayer/issues/7647
)
).
(
[
#7647
](
https://github.com/google/ExoPlayer/issues/7647
)
).
...
...
library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java
View file @
1c7c6fb9
...
@@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat;
...
@@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteOpenHelper
;
import
android.database.sqlite.SQLiteOpenHelper
;
import
android.net.Uri
;
import
android.text.SpannableString
;
import
android.text.SpannableString
;
import
android.text.Spanned
;
import
android.text.Spanned
;
import
android.text.style.StrikethroughSpan
;
import
android.text.style.StrikethroughSpan
;
...
@@ -127,13 +128,39 @@ public class UtilTest {
...
@@ -127,13 +128,39 @@ public class UtilTest {
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/Manifest"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/Manifest"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.isml/manifest"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.isml/manifest"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.isml/manifest(filter=x)"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.isml/manifest(filter=x)"
)).
isEqualTo
(
C
.
TYPE_SS
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.isml/manifest_hd"
)).
isEqualTo
(
C
.
TYPE_SS
);
}
}
@Test
@Test
public
void
inferContentType_handlesOtherIsmUris
()
{
public
void
inferContentType_handlesOtherIsmUris
()
{
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/video.mp4"
)).
isEqualTo
(
C
.
TYPE_OTHER
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/video.mp4"
)).
isEqualTo
(
C
.
TYPE_OTHER
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/prefix-manifest"
)).
isEqualTo
(
C
.
TYPE_OTHER
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/prefix-manifest"
)).
isEqualTo
(
C
.
TYPE_OTHER
);
assertThat
(
Util
.
inferContentType
(
"http://a.b/c.ism/manifest-suffix"
)).
isEqualTo
(
C
.
TYPE_OTHER
);
}
@Test
public
void
fixSmoothStreamingIsmManifestUri_addsManifestSuffix
()
{
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.ism"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.isml"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.isml/Manifest"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.ism/"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.isml/"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.isml/Manifest"
));
}
@Test
public
void
fixSmoothStreamingIsmManifestUri_doesNotAlterManifestUri
()
{
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.isml/Manifest"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.isml/Manifest"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest(filter=x)"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest(filter=x)"
));
assertThat
(
Util
.
fixSmoothStreamingIsmManifestUri
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest_hd"
)))
.
isEqualTo
(
Uri
.
parse
(
"http://a.b/c.ism/Manifest_hd"
));
}
}
@Test
@Test
...
...
library/core/src/main/java/com/google/android/exoplayer2/util/Util.java
View file @
1c7c6fb9
...
@@ -136,8 +136,7 @@ public final class Util {
...
@@ -136,8 +136,7 @@ public final class Util {
private
static
final
Pattern
ESCAPED_CHARACTER_PATTERN
=
Pattern
.
compile
(
"%([A-Fa-f0-9]{2})"
);
private
static
final
Pattern
ESCAPED_CHARACTER_PATTERN
=
Pattern
.
compile
(
"%([A-Fa-f0-9]{2})"
);
// https://docs.microsoft.com/en-us/azure/media-services/previous/media-services-deliver-content-overview#URLs.
// https://docs.microsoft.com/en-us/azure/media-services/previous/media-services-deliver-content-overview#URLs.
private
static
final
Pattern
ISM_URL_PATTERN
=
private
static
final
Pattern
ISM_URL_PATTERN
=
Pattern
.
compile
(
".*\\.isml?(?:/(manifest(.*))?)?"
);
Pattern
.
compile
(
".*\\.ism(?:l)?(?:/(?:manifest(?:\\((.+)\\))?)?)?"
);
private
static
final
String
ISM_HLS_FORMAT_EXTENSION
=
"format=m3u8-aapl"
;
private
static
final
String
ISM_HLS_FORMAT_EXTENSION
=
"format=m3u8-aapl"
;
private
static
final
String
ISM_DASH_FORMAT_EXTENSION
=
"format=mpd-time-csf"
;
private
static
final
String
ISM_DASH_FORMAT_EXTENSION
=
"format=mpd-time-csf"
;
...
@@ -1608,7 +1607,7 @@ public final class Util {
...
@@ -1608,7 +1607,7 @@ public final class Util {
}
}
Matcher
ismMatcher
=
ISM_URL_PATTERN
.
matcher
(
fileName
);
Matcher
ismMatcher
=
ISM_URL_PATTERN
.
matcher
(
fileName
);
if
(
ismMatcher
.
matches
())
{
if
(
ismMatcher
.
matches
())
{
@Nullable
String
extensions
=
ismMatcher
.
group
(
1
);
@Nullable
String
extensions
=
ismMatcher
.
group
(
2
);
if
(
extensions
!=
null
)
{
if
(
extensions
!=
null
)
{
if
(
extensions
.
contains
(
ISM_DASH_FORMAT_EXTENSION
))
{
if
(
extensions
.
contains
(
ISM_DASH_FORMAT_EXTENSION
))
{
return
C
.
TYPE_DASH
;
return
C
.
TYPE_DASH
;
...
@@ -1622,6 +1621,27 @@ public final class Util {
...
@@ -1622,6 +1621,27 @@ public final class Util {
}
}
/**
/**
* If the provided URI is an ISM Presentation URI, returns the URI with "Manifest" appended to its
* path (i.e., the corresponding default manifest URI). Else returns the provided URI without
* modification. See [MS-SSTR] v20180912, section 2.2.1.
*
* @param uri The original URI.
* @return The fixed URI.
*/
public
static
Uri
fixSmoothStreamingIsmManifestUri
(
Uri
uri
)
{
@Nullable
String
path
=
toLowerInvariant
(
uri
.
getPath
());
if
(
path
==
null
)
{
return
uri
;
}
Matcher
ismMatcher
=
ISM_URL_PATTERN
.
matcher
(
path
);
if
(
ismMatcher
.
matches
()
&&
ismMatcher
.
group
(
1
)
==
null
)
{
// Add missing "Manifest" suffix.
return
Uri
.
withAppendedPath
(
uri
,
"Manifest"
);
}
return
uri
;
}
/**
* Returns the specified millisecond time formatted as a string.
* Returns the specified millisecond time formatted as a string.
*
*
* @param builder The builder that {@code formatter} will write to.
* @param builder The builder that {@code formatter} will write to.
...
...
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java
View file @
1c7c6fb9
...
@@ -39,7 +39,6 @@ import com.google.android.exoplayer2.source.SinglePeriodTimeline;
...
@@ -39,7 +39,6 @@ import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil
;
import
com.google.android.exoplayer2.upstream.Allocator
;
import
com.google.android.exoplayer2.upstream.Allocator
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy
;
...
@@ -50,6 +49,7 @@ import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
...
@@ -50,6 +49,7 @@ import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -531,7 +531,7 @@ public final class SsMediaSource extends BaseMediaSource
...
@@ -531,7 +531,7 @@ public final class SsMediaSource extends BaseMediaSource
@Nullable
Object
tag
)
{
@Nullable
Object
tag
)
{
Assertions
.
checkState
(
manifest
==
null
||
!
manifest
.
isLive
);
Assertions
.
checkState
(
manifest
==
null
||
!
manifest
.
isLive
);
this
.
manifest
=
manifest
;
this
.
manifest
=
manifest
;
this
.
manifestUri
=
manifestUri
==
null
?
null
:
SsUtil
.
fix
ManifestUri
(
manifestUri
);
this
.
manifestUri
=
manifestUri
==
null
?
null
:
Util
.
fixSmoothStreamingIsm
ManifestUri
(
manifestUri
);
this
.
manifestDataSourceFactory
=
manifestDataSourceFactory
;
this
.
manifestDataSourceFactory
=
manifestDataSourceFactory
;
this
.
manifestParser
=
manifestParser
;
this
.
manifestParser
=
manifestParser
;
this
.
chunkSourceFactory
=
chunkSourceFactory
;
this
.
chunkSourceFactory
=
chunkSourceFactory
;
...
...
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsUtil.java
deleted
100644 → 0
View file @
590e81e5
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
source
.
smoothstreaming
.
manifest
;
import
android.net.Uri
;
import
com.google.android.exoplayer2.util.Util
;
/** SmoothStreaming related utility methods. */
public
final
class
SsUtil
{
/** Returns a fixed SmoothStreaming client manifest {@link Uri}. */
public
static
Uri
fixManifestUri
(
Uri
manifestUri
)
{
String
lastPathSegment
=
manifestUri
.
getLastPathSegment
();
if
(
lastPathSegment
!=
null
&&
Util
.
toLowerInvariant
(
lastPathSegment
).
matches
(
"manifest(\\(.+\\))?"
))
{
return
manifestUri
;
}
return
Uri
.
withAppendedPath
(
manifestUri
,
"Manifest"
);
}
private
SsUtil
()
{}
}
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java
View file @
1c7c6fb9
...
@@ -23,10 +23,10 @@ import com.google.android.exoplayer2.offline.StreamKey;
...
@@ -23,10 +23,10 @@ import com.google.android.exoplayer2.offline.StreamKey;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser
;
import
com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.util.Util
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -64,7 +64,7 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
...
@@ -64,7 +64,7 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
*/
*/
public
SsDownloader
(
public
SsDownloader
(
Uri
manifestUri
,
List
<
StreamKey
>
streamKeys
,
DownloaderConstructorHelper
constructorHelper
)
{
Uri
manifestUri
,
List
<
StreamKey
>
streamKeys
,
DownloaderConstructorHelper
constructorHelper
)
{
super
(
SsUtil
.
fix
ManifestUri
(
manifestUri
),
streamKeys
,
constructorHelper
);
super
(
Util
.
fixSmoothStreamingIsm
ManifestUri
(
manifestUri
),
streamKeys
,
constructorHelper
);
}
}
@Override
@Override
...
...
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