Skip to content

Commit

Permalink
Added Captions example to the sample. (#670)
Browse files Browse the repository at this point in the history
Allow for player to reselect default track.
Allow for player to check if renderer type is enabled.
  • Loading branch information
hansenji authored and brianwernick committed Nov 17, 2018
1 parent 89b96b8 commit c0f4bc3
Show file tree
Hide file tree
Showing 17 changed files with 1,387 additions and 4 deletions.
15 changes: 15 additions & 0 deletions demo/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
buildscript {
ext.kotlinVersion = '1.2.71'
repositories {
google()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'


dependencies {
implementation project(':library')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"

implementation "com.android.support:appcompat-v7:$rootProject.ext.supportLibVersion"
implementation "com.android.support:support-media-compat:$rootProject.ext.supportLibVersion"
implementation "com.google.android.exoplayer:extension-okhttp:$rootProject.ext.exoPlayerVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.AppCompatImageButton;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.devbrackets.android.exomedia.ExoMedia;
import com.devbrackets.android.exomedia.listener.VideoControlsSeekListener;
import com.devbrackets.android.exomedia.ui.widget.VideoControls;
import com.devbrackets.android.exomedia.ui.widget.VideoControlsCore;
import com.devbrackets.android.exomedia.ui.widget.VideoView;
import com.devbrackets.android.exomediademo.App;
import com.devbrackets.android.exomediademo.R;
import com.devbrackets.android.exomediademo.data.MediaItem;
import com.devbrackets.android.exomediademo.data.Samples;
import com.devbrackets.android.exomediademo.manager.PlaylistManager;
import com.devbrackets.android.exomediademo.playlist.VideoApi;
import com.devbrackets.android.exomediademo.ui.subtitle.AspectRatioFrameLayout;
import com.devbrackets.android.exomediademo.ui.subtitle.SubtitleView;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.EventLogger;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;


public class VideoPlayerActivity extends Activity implements VideoControlsSeekListener {
Expand All @@ -24,6 +38,9 @@ public class VideoPlayerActivity extends Activity implements VideoControlsSeekLi
protected VideoApi videoApi;
protected VideoView videoView;
protected PlaylistManager playlistManager;
protected AspectRatioFrameLayout subtitleFrameLayout;
protected SubtitleView subtitleView;
protected AppCompatImageButton captionsButton;

protected int selectedIndex;

Expand Down Expand Up @@ -73,11 +90,37 @@ protected void retrieveExtras() {
protected void init() {
setupPlaylistManager();

subtitleView = findViewById(R.id.subtitleView);
videoView = findViewById(R.id.video_play_activity_video_view);
subtitleFrameLayout = findViewById(R.id.video_player_activity_subtitle_frame_layout);

captionsButton = new AppCompatImageButton(this);
captionsButton.setBackgroundResource(android.R.color.transparent);
captionsButton.setImageResource(R.drawable.ic_closed_caption_white_24dp);
captionsButton.setOnClickListener(v -> showCaptionsMenu());

videoView.setHandleAudioFocus(false);
videoView.getVideoControls().setSeekListener(this);
VideoControlsCore videoControlsCore = videoView.getVideoControlsCore();
if (videoControlsCore instanceof VideoControls) {
VideoControls videoControls = (VideoControls) videoControlsCore;
videoControls.setSeekListener(this);
if (videoView.trackSelectionAvailable()) {
videoControls.addExtraView(captionsButton);
}
}
videoView.setAnalyticsListener(new EventLogger(null));

videoView.setOnVideoSizedChangedListener((intrinsicWidth, intrinsicHeight, pixelWidthHeightRatio) -> {
float videoAspectRatio;
if (intrinsicWidth == 0 || intrinsicHeight == 0) {
videoAspectRatio = 1F;
} else {
videoAspectRatio = intrinsicWidth * pixelWidthHeightRatio / intrinsicHeight;
}
subtitleFrameLayout.setAspectRatio(videoAspectRatio);
});
videoView.setCaptionListener(subtitleView);

videoApi = new VideoApi(videoView);
playlistManager.addVideoApi(videoApi);
playlistManager.play(0, false);
Expand All @@ -99,4 +142,88 @@ private void setupPlaylistManager() {
playlistManager.setParameters(mediaItems, selectedIndex);
playlistManager.setId(PLAYLIST_ID);
}

private void showCaptionsMenu() {
Map<ExoMedia.RendererType, TrackGroupArray> availableTracks = videoView.getAvailableTracks();
if (availableTracks == null) {
return;
}
TrackGroupArray trackGroupArray = availableTracks.get(ExoMedia.RendererType.CLOSED_CAPTION);
if (trackGroupArray == null || trackGroupArray.isEmpty()) {
return;
}

PopupMenu popupMenu = new PopupMenu(this, captionsButton);
Menu menu = popupMenu.getMenu();
// Add Menu Items
MenuItem disabledItem = menu.add(0, CC_DISABLED, 0, getString(R.string.disable));
disabledItem.setCheckable(true);
MenuItem defaultItem = menu.add(0, CC_DEFAULT, 0, getString(R.string.auto));
defaultItem.setCheckable(true);

boolean selected = false;
for (int groupIndex = 0; groupIndex < trackGroupArray.length; groupIndex++) {
int selectedIndex = videoView.getSelectedTrackIndex(ExoMedia.RendererType.CLOSED_CAPTION, groupIndex);
Log.d("Captions", "Selected Caption Track: " + groupIndex + " | " + selectedIndex);
TrackGroup trackGroup = trackGroupArray.get(groupIndex);
for (int index = 0; index < trackGroup.length; index++) {
Format format = trackGroup.getFormat(index);

// Skip over non text formats.
if (!format.sampleMimeType.startsWith("text")) {
continue;
}

String title = format.label;
if (title == null) {
title = format.language;
}
if (title == null) {
title = format.id;
}
if (title == null) {
title = groupIndex + ":" + index;
}

int itemId = groupIndex * CC_GROUP_INDEX_MOD + index;
MenuItem item = menu.add(0, itemId, 0, title);
item.setCheckable(true);
if (index == selectedIndex) {
item.setChecked(true);
selected = true;
}
}
}

if (!selected) {
if (videoView.isRendererEnabled(ExoMedia.RendererType.CLOSED_CAPTION)) {
defaultItem.setChecked(true);
} else {
disabledItem.setChecked(true);
}
}

menu.setGroupCheckable(0, true, true);
popupMenu.setOnMenuItemClickListener(menuItem -> onTrackSelected(menuItem));
popupMenu.show();
}

private static final int CC_GROUP_INDEX_MOD = 1000;
private static final int CC_DISABLED = -1001;
private static final int CC_DEFAULT = -1000;

private boolean onTrackSelected(MenuItem menuItem) {
menuItem.setChecked(true);
int itemId = menuItem.getItemId();
if (itemId == CC_DEFAULT) {
videoView.clearSelectedTracks(ExoMedia.RendererType.CLOSED_CAPTION);
} else if (itemId == CC_DISABLED) {
videoView.setRendererEnabled(ExoMedia.RendererType.CLOSED_CAPTION, false);
} else {
int trackIndex = itemId % CC_GROUP_INDEX_MOD;
int groupIndex = itemId / CC_GROUP_INDEX_MOD;
videoView.setTrack(ExoMedia.RendererType.CLOSED_CAPTION, groupIndex, trackIndex);
}
return true;
}
}
Loading

0 comments on commit c0f4bc3

Please sign in to comment.