From 82b26357c96fda3590582f71de6656123b4f6fbc Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 11 Aug 2020 14:53:13 +0100 Subject: [PATCH] Infer ISM content type from URL specified extension PiperOrigin-RevId: 326012248 --- .../google/android/exoplayer2/util/Util.java | 23 +++++++++-- .../android/exoplayer2/util/UtilTest.java | 38 ++++++++++++++++++- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java index 2457f09bcc..9f3ed2f487 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -141,6 +141,12 @@ public final class Util { + "(T(([0-9]*)H)?(([0-9]*)M)?(([0-9.]*)S)?)?$"); 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. + private static final Pattern ISM_URL_PATTERN = + Pattern.compile(".*\\.ism(?:l)?(?:/(?:manifest(?:\\((.+)\\))?)?)?"); + private static final String ISM_HLS_FORMAT_EXTENSION = "format=m3u8-aapl"; + private static final String ISM_DASH_FORMAT_EXTENSION = "format=mpd-time-csf"; + // Replacement map of ISO language codes used for normalization. @Nullable private static HashMap languageTagReplacementMap; @@ -1714,11 +1720,20 @@ public final class Util { return C.TYPE_DASH; } else if (fileName.endsWith(".m3u8")) { return C.TYPE_HLS; - } else if (fileName.matches(".*\\.ism(l)?(/manifest(\\(.+\\))?)?")) { - return C.TYPE_SS; - } else { - return C.TYPE_OTHER; } + Matcher ismMatcher = ISM_URL_PATTERN.matcher(fileName); + if (ismMatcher.matches()) { + @Nullable String extensions = ismMatcher.group(1); + if (extensions != null) { + if (extensions.contains(ISM_DASH_FORMAT_EXTENSION)) { + return C.TYPE_DASH; + } else if (extensions.contains(ISM_HLS_FORMAT_EXTENSION)) { + return C.TYPE_HLS; + } + } + return C.TYPE_SS; + } + return C.TYPE_OTHER; } /** diff --git a/library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java b/library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java index f265c3ccb7..0bf5028282 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/util/UtilTest.java @@ -89,13 +89,49 @@ public class UtilTest { } @Test - public void inferContentType_returnsInferredResult() { + public void inferContentType_handlesHlsIsmUris() { + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(format=m3u8-aapl)")) + .isEqualTo(C.TYPE_HLS); + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(format=m3u8-aapl,quality=hd)")) + .isEqualTo(C.TYPE_HLS); + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(quality=hd,format=m3u8-aapl)")) + .isEqualTo(C.TYPE_HLS); + } + + @Test + public void inferContentType_handlesHlsIsmV3Uris() { + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(format=m3u8-aapl-v3)")) + .isEqualTo(C.TYPE_HLS); + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(format=m3u8-aapl-v3,quality=hd)")) + .isEqualTo(C.TYPE_HLS); + assertThat(Util.inferContentType("http://a.b/c.ism/manifest(quality=hd,format=m3u8-aapl-v3)")) + .isEqualTo(C.TYPE_HLS); + } + + @Test + public void inferContentType_handlesDashIsmUris() { + assertThat(Util.inferContentType("http://a.b/c.isml/manifest(format=mpd-time-csf)")) + .isEqualTo(C.TYPE_DASH); + assertThat(Util.inferContentType("http://a.b/c.isml/manifest(format=mpd-time-csf,quality=hd)")) + .isEqualTo(C.TYPE_DASH); + assertThat(Util.inferContentType("http://a.b/c.isml/manifest(quality=hd,format=mpd-time-csf)")) + .isEqualTo(C.TYPE_DASH); + } + + @Test + public void inferContentType_handlesSmoothStreamingIsmUris() { assertThat(Util.inferContentType("http://a.b/c.ism")).isEqualTo(C.TYPE_SS); assertThat(Util.inferContentType("http://a.b/c.isml")).isEqualTo(C.TYPE_SS); + assertThat(Util.inferContentType("http://a.b/c.ism/")).isEqualTo(C.TYPE_SS); + assertThat(Util.inferContentType("http://a.b/c.isml/")).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(filter=x)")).isEqualTo(C.TYPE_SS); + } + @Test + 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/prefix-manifest")).isEqualTo(C.TYPE_OTHER); assertThat(Util.inferContentType("http://a.b/c.ism/manifest-suffix")).isEqualTo(C.TYPE_OTHER); }