Commit 799d281e by andrewlewis Committed by Oliver Woodman

Add support for registering custom MIME types

Also add a few missing MP4 object types.

Issue: #4264

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=199778373
parent 7bf98b9f
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
([#4315](https://github.com/google/ExoPlayer/issues/4315)). ([#4315](https://github.com/google/ExoPlayer/issues/4315)).
* Set `METADATA_KEY_TITLE` on media descriptions * Set `METADATA_KEY_TITLE` on media descriptions
((#4292)[https://github.com/google/ExoPlayer/issues/4292]). ((#4292)[https://github.com/google/ExoPlayer/issues/4292]).
* Allow apps to register custom MIME types
([#4264](https://github.com/google/ExoPlayer/issues/4264)).
### 2.8.1 ### ### 2.8.1 ###
......
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.util; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.util;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import java.util.ArrayList;
/** /**
* Defines common MIME types and helper methods. * Defines common MIME types and helper methods.
...@@ -92,7 +93,29 @@ public final class MimeTypes { ...@@ -92,7 +93,29 @@ public final class MimeTypes {
public static final String APPLICATION_DVBSUBS = BASE_TYPE_APPLICATION + "/dvbsubs"; public static final String APPLICATION_DVBSUBS = BASE_TYPE_APPLICATION + "/dvbsubs";
public static final String APPLICATION_EXIF = BASE_TYPE_APPLICATION + "/x-exif"; public static final String APPLICATION_EXIF = BASE_TYPE_APPLICATION + "/x-exif";
private MimeTypes() {} private static final ArrayList<CustomMimeType> customMimeTypes = new ArrayList<>();
/**
* Registers a custom MIME type. Most applications do not need to call this method, as handling of
* standard MIME types is built in. These built-in MIME types take precedence over any registered
* via this method. If this method is used, it must be called before creating any player(s).
*
* @param mimeType The custom MIME type to register.
* @param codecPrefix The RFC 6381-style codec string prefix associated with the MIME type.
* @param trackType The {@link C}{@code .TRACK_TYPE_*} constant associated with the MIME type.
* This value is ignored if the top-level type of {@code mimeType} is audio, video or text.
*/
public static void registerCustomMimeType(String mimeType, String codecPrefix, int trackType) {
CustomMimeType customMimeType = new CustomMimeType(mimeType, codecPrefix, trackType);
int customMimeTypeCount = customMimeTypes.size();
for (int i = 0; i < customMimeTypeCount; i++) {
if (mimeType.equals(customMimeTypes.get(i).mimeType)) {
customMimeTypes.remove(i);
break;
}
}
customMimeTypes.add(customMimeType);
}
/** /**
* Whether the top-level type of {@code mimeType} is audio. * Whether the top-level type of {@code mimeType} is audio.
...@@ -222,8 +245,9 @@ public final class MimeTypes { ...@@ -222,8 +245,9 @@ public final class MimeTypes {
return MimeTypes.AUDIO_OPUS; return MimeTypes.AUDIO_OPUS;
} else if (codec.startsWith("vorbis")) { } else if (codec.startsWith("vorbis")) {
return MimeTypes.AUDIO_VORBIS; return MimeTypes.AUDIO_VORBIS;
} else {
return getCustomMimeTypeForCodec(codec);
} }
return null;
} }
/** /**
...@@ -236,18 +260,28 @@ public final class MimeTypes { ...@@ -236,18 +260,28 @@ public final class MimeTypes {
@Nullable @Nullable
public static String getMimeTypeFromMp4ObjectType(int objectType) { public static String getMimeTypeFromMp4ObjectType(int objectType) {
switch (objectType) { switch (objectType) {
case 0x60:
case 0x61:
return MimeTypes.VIDEO_MPEG2;
case 0x20: case 0x20:
return MimeTypes.VIDEO_MP4V; return MimeTypes.VIDEO_MP4V;
case 0x21: case 0x21:
return MimeTypes.VIDEO_H264; return MimeTypes.VIDEO_H264;
case 0x23: case 0x23:
return MimeTypes.VIDEO_H265; return MimeTypes.VIDEO_H265;
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
return MimeTypes.VIDEO_MPEG2;
case 0x6A:
return MimeTypes.VIDEO_MPEG;
case 0x69: case 0x69:
case 0x6B: case 0x6B:
return MimeTypes.AUDIO_MPEG; return MimeTypes.AUDIO_MPEG;
case 0xA3:
return MimeTypes.VIDEO_VC1;
case 0xB1:
return MimeTypes.VIDEO_VP9;
case 0x40: case 0x40:
case 0x66: case 0x66:
case 0x67: case 0x67:
...@@ -298,7 +332,7 @@ public final class MimeTypes { ...@@ -298,7 +332,7 @@ public final class MimeTypes {
|| APPLICATION_CAMERA_MOTION.equals(mimeType)) { || APPLICATION_CAMERA_MOTION.equals(mimeType)) {
return C.TRACK_TYPE_METADATA; return C.TRACK_TYPE_METADATA;
} else { } else {
return C.TRACK_TYPE_UNKNOWN; return getTrackTypeForCustomMimeType(mimeType);
} }
} }
...@@ -355,4 +389,41 @@ public final class MimeTypes { ...@@ -355,4 +389,41 @@ public final class MimeTypes {
return mimeType.substring(0, indexOfSlash); return mimeType.substring(0, indexOfSlash);
} }
private static @Nullable String getCustomMimeTypeForCodec(String codec) {
int customMimeTypeCount = customMimeTypes.size();
for (int i = 0; i < customMimeTypeCount; i++) {
CustomMimeType customMimeType = customMimeTypes.get(i);
if (codec.startsWith(customMimeType.codecPrefix)) {
return customMimeType.mimeType;
}
}
return null;
}
private static int getTrackTypeForCustomMimeType(String mimeType) {
int customMimeTypeCount = customMimeTypes.size();
for (int i = 0; i < customMimeTypeCount; i++) {
CustomMimeType customMimeType = customMimeTypes.get(i);
if (mimeType.equals(customMimeType.mimeType)) {
return customMimeType.trackType;
}
}
return C.TRACK_TYPE_UNKNOWN;
}
private MimeTypes() {
// Prevent instantiation.
}
private static final class CustomMimeType {
public final String mimeType;
public final String codecPrefix;
public final int trackType;
public CustomMimeType(String mimeType, String codecPrefix, int trackType) {
this.mimeType = mimeType;
this.codecPrefix = codecPrefix;
this.trackType = trackType;
}
}
} }
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