mirror of
https://github.com/androidx/media.git
synced 2025-05-14 19:19:58 +08:00
Add support for subtitle files in the demo app
issue:#5523 PiperOrigin-RevId: 277927555
This commit is contained in:
parent
c5c50078d7
commit
07e93c15f9
@ -113,6 +113,8 @@
|
||||
* Update the ffmpeg extension to release 4.2. It is necessary to rebuild the
|
||||
native part of the extension after this change, following the instructions in
|
||||
the extension's readme.
|
||||
* Add support for subtitle files to the demo app
|
||||
([#5523](https://github.com/google/ExoPlayer/issues/5523)).
|
||||
|
||||
### 2.10.6 (2019-10-17) ###
|
||||
|
||||
|
@ -582,5 +582,17 @@
|
||||
"spherical_stereo_mode": "top_bottom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Subtitles",
|
||||
"samples": [
|
||||
{
|
||||
"name": "TTML",
|
||||
"uri": "https://html5demos.com/assets/dizzy.mp4",
|
||||
"subtitle_uri": "https://storage.googleapis.com/exoplayer-test-media-1/ttml/netflix_ttml_sample.xml",
|
||||
"subtitle_mime_type": "application/ttml+xml",
|
||||
"subtitle_language": "en"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -34,6 +34,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.C.ContentType;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.PlaybackPreparer;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
@ -53,7 +54,9 @@ import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||
import com.google.android.exoplayer2.source.MergingMediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
||||
@ -114,8 +117,11 @@ public class PlayerActivity extends AppCompatActivity
|
||||
public static final String DRM_KEY_REQUEST_PROPERTIES_EXTRA = "drm_key_request_properties";
|
||||
public static final String DRM_MULTI_SESSION_EXTRA = "drm_multi_session";
|
||||
public static final String PREFER_EXTENSION_DECODERS_EXTRA = "prefer_extension_decoders";
|
||||
public static final String TUNNELING = "tunneling";
|
||||
public static final String TUNNELING_EXTRA = "tunneling";
|
||||
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
|
||||
public static final String SUBTITLE_URI_EXTRA = "subtitle_uri";
|
||||
public static final String SUBTITLE_MIME_TYPE_EXTRA = "subtitle_mime_type";
|
||||
public static final String SUBTITLE_LANGUAGE_EXTRA = "subtitle_language";
|
||||
// For backwards compatibility only.
|
||||
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
|
||||
@ -204,7 +210,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
} else {
|
||||
DefaultTrackSelector.ParametersBuilder builder =
|
||||
new DefaultTrackSelector.ParametersBuilder(/* context= */ this);
|
||||
boolean tunneling = intent.getBooleanExtra(TUNNELING, false);
|
||||
boolean tunneling = intent.getBooleanExtra(TUNNELING_EXTRA, false);
|
||||
if (Util.SDK_INT >= 21 && tunneling) {
|
||||
builder.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(/* context= */ this));
|
||||
}
|
||||
@ -424,6 +430,19 @@ public class PlayerActivity extends AppCompatActivity
|
||||
MediaSource[] mediaSources = new MediaSource[samples.length];
|
||||
for (int i = 0; i < samples.length; i++) {
|
||||
mediaSources[i] = createLeafMediaSource(samples[i]);
|
||||
Sample.SubtitleInfo subtitleInfo = samples[i].subtitleInfo;
|
||||
if (subtitleInfo != null) {
|
||||
Format subtitleFormat =
|
||||
Format.createTextSampleFormat(
|
||||
/* id= */ null,
|
||||
subtitleInfo.mimeType,
|
||||
/* selectionFlags= */ 0,
|
||||
subtitleInfo.language);
|
||||
MediaSource subtitleMediaSource =
|
||||
new SingleSampleMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(subtitleInfo.uri, subtitleFormat, C.TIME_UNSET);
|
||||
mediaSources[i] = new MergingMediaSource(mediaSources[i], subtitleMediaSource);
|
||||
}
|
||||
}
|
||||
MediaSource mediaSource =
|
||||
mediaSources.length == 1 ? mediaSources[0] : new ConcatenatingMediaSource(mediaSources);
|
||||
|
@ -24,6 +24,9 @@ import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_SCHEME_EXTRA
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_SCHEME_UUID_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.EXTENSION_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.IS_LIVE_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.SUBTITLE_LANGUAGE_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.SUBTITLE_MIME_TYPE_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.SUBTITLE_URI_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.URI_EXTRA;
|
||||
|
||||
import android.content.Intent;
|
||||
@ -51,7 +54,8 @@ import java.util.UUID;
|
||||
isLive,
|
||||
DrmInfo.createFromIntent(intent, extrasKeySuffix),
|
||||
adTagUri,
|
||||
/* sphericalStereoMode= */ null);
|
||||
/* sphericalStereoMode= */ null,
|
||||
SubtitleInfo.createFromIntent(intent, extrasKeySuffix));
|
||||
}
|
||||
|
||||
public final Uri uri;
|
||||
@ -60,6 +64,7 @@ import java.util.UUID;
|
||||
public final DrmInfo drmInfo;
|
||||
public final Uri adTagUri;
|
||||
@Nullable public final String sphericalStereoMode;
|
||||
@Nullable SubtitleInfo subtitleInfo;
|
||||
|
||||
public UriSample(
|
||||
String name,
|
||||
@ -68,7 +73,8 @@ import java.util.UUID;
|
||||
boolean isLive,
|
||||
DrmInfo drmInfo,
|
||||
Uri adTagUri,
|
||||
@Nullable String sphericalStereoMode) {
|
||||
@Nullable String sphericalStereoMode,
|
||||
@Nullable SubtitleInfo subtitleInfo) {
|
||||
super(name);
|
||||
this.uri = uri;
|
||||
this.extension = extension;
|
||||
@ -76,6 +82,7 @@ import java.util.UUID;
|
||||
this.drmInfo = drmInfo;
|
||||
this.adTagUri = adTagUri;
|
||||
this.sphericalStereoMode = sphericalStereoMode;
|
||||
this.subtitleInfo = subtitleInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,6 +107,9 @@ import java.util.UUID;
|
||||
if (drmInfo != null) {
|
||||
drmInfo.addToIntent(intent, extrasKeySuffix);
|
||||
}
|
||||
if (subtitleInfo != null) {
|
||||
subtitleInfo.addToIntent(intent, extrasKeySuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,6 +177,36 @@ import java.util.UUID;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class SubtitleInfo {
|
||||
|
||||
@Nullable
|
||||
public static SubtitleInfo createFromIntent(Intent intent, String extrasKeySuffix) {
|
||||
if (!intent.hasExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix)) {
|
||||
return null;
|
||||
}
|
||||
return new SubtitleInfo(
|
||||
Uri.parse(intent.getStringExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix)),
|
||||
intent.getStringExtra(SUBTITLE_MIME_TYPE_EXTRA + extrasKeySuffix),
|
||||
intent.getStringExtra(SUBTITLE_LANGUAGE_EXTRA + extrasKeySuffix));
|
||||
}
|
||||
|
||||
public final Uri uri;
|
||||
public final String mimeType;
|
||||
@Nullable public final String language;
|
||||
|
||||
public SubtitleInfo(Uri uri, String mimeType, @Nullable String language) {
|
||||
this.uri = Assertions.checkNotNull(uri);
|
||||
this.mimeType = Assertions.checkNotNull(mimeType);
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public void addToIntent(Intent intent, String extrasKeySuffix) {
|
||||
intent.putExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix, uri.toString());
|
||||
intent.putExtra(SUBTITLE_MIME_TYPE_EXTRA + extrasKeySuffix, mimeType);
|
||||
intent.putExtra(SUBTITLE_LANGUAGE_EXTRA + extrasKeySuffix, language);
|
||||
}
|
||||
}
|
||||
|
||||
public static Sample createFromIntent(Intent intent) {
|
||||
if (ACTION_VIEW_LIST.equals(intent.getAction())) {
|
||||
ArrayList<String> intentUris = new ArrayList<>();
|
||||
|
@ -178,7 +178,7 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
? PlayerActivity.ABR_ALGORITHM_RANDOM
|
||||
: PlayerActivity.ABR_ALGORITHM_DEFAULT;
|
||||
intent.putExtra(PlayerActivity.ABR_ALGORITHM_EXTRA, abrAlgorithm);
|
||||
intent.putExtra(PlayerActivity.TUNNELING, isNonNullAndChecked(tunnelingMenuItem));
|
||||
intent.putExtra(PlayerActivity.TUNNELING_EXTRA, isNonNullAndChecked(tunnelingMenuItem));
|
||||
sample.addToIntent(intent);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
@ -311,6 +311,10 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
ArrayList<UriSample> playlistSamples = null;
|
||||
String adTagUri = null;
|
||||
String sphericalStereoMode = null;
|
||||
List<Sample.SubtitleInfo> subtitleInfos = new ArrayList<>();
|
||||
Uri subtitleUri = null;
|
||||
String subtitleMimeType = null;
|
||||
String subtitleLanguage = null;
|
||||
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
@ -352,7 +356,7 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
playlistSamples = new ArrayList<>();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
playlistSamples.add((UriSample) readEntry(reader, true));
|
||||
playlistSamples.add((UriSample) readEntry(reader, /* insidePlaylist= */ true));
|
||||
}
|
||||
reader.endArray();
|
||||
break;
|
||||
@ -364,6 +368,15 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
!insidePlaylist, "Invalid attribute on nested item: spherical_stereo_mode");
|
||||
sphericalStereoMode = reader.nextString();
|
||||
break;
|
||||
case "subtitle_uri":
|
||||
subtitleUri = Uri.parse(reader.nextString());
|
||||
break;
|
||||
case "subtitle_mime_type":
|
||||
subtitleMimeType = reader.nextString();
|
||||
break;
|
||||
case "subtitle_language":
|
||||
subtitleLanguage = reader.nextString();
|
||||
break;
|
||||
default:
|
||||
throw new ParserException("Unsupported attribute name: " + name);
|
||||
}
|
||||
@ -377,6 +390,14 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
drmLicenseUrl,
|
||||
drmKeyRequestProperties,
|
||||
drmMultiSession);
|
||||
Sample.SubtitleInfo subtitleInfo =
|
||||
subtitleUri == null
|
||||
? null
|
||||
: new Sample.SubtitleInfo(
|
||||
subtitleUri,
|
||||
Assertions.checkNotNull(
|
||||
subtitleMimeType, "subtitle_mime_type is required if subtitle_uri is set."),
|
||||
subtitleLanguage);
|
||||
if (playlistSamples != null) {
|
||||
UriSample[] playlistSamplesArray = playlistSamples.toArray(new UriSample[0]);
|
||||
return new PlaylistSample(sampleName, playlistSamplesArray);
|
||||
@ -388,7 +409,8 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
isLive,
|
||||
drmInfo,
|
||||
adTagUri != null ? Uri.parse(adTagUri) : null,
|
||||
sphericalStereoMode);
|
||||
sphericalStereoMode,
|
||||
subtitleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user