Commit e2ea849d authored by Hampton Maxwell's avatar Hampton Maxwell
Browse files

Add ability to sideload text tracks and report them in onLoad

parent a1a4e0c4
Loading
Loading
Loading
Loading
+64 −18
Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java: 64 added lines, 18 removed lines.
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@ import android.widget.FrameLayout;
import com.brentvatne.react.R;
import com.brentvatne.receiver.AudioBecomingNoisyReceiver;
import com.brentvatne.receiver.BecomingNoisyListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
@@ -62,7 +67,6 @@ import java.net.CookiePolicy;
import java.lang.Math;
import java.lang.Object;
import java.util.ArrayList;
import java.util.Arrays;

@SuppressLint("ViewConstructor")
class ReactExoplayerView extends FrameLayout implements
@@ -108,6 +112,7 @@ class ReactExoplayerView extends FrameLayout implements
    private boolean repeat;
    private String textTrackType;
    private Dynamic textTrackValue;
    private ReadableArray textTracks;
    private boolean disableFocus;
    private float mProgressUpdateInterval = 250.0f;
    private boolean playInBackground = false;
@@ -234,25 +239,17 @@ class ReactExoplayerView extends FrameLayout implements
            player.setPlaybackParameters(params);
        }
        if (playerNeedsSource && srcUri != null) {
            ArrayList<MediaSource> mediaSources = new ArrayList<>();
            mediaSources.add(buildMediaSource(srcUri, extension)); // video source
            MediaSource text0 = buildTextSource(
                    "ES VTT",
                    Uri.parse("https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_es.vtt"),
                    "vtt",
                    "es"
            );
            if (text0 != null) {
                mediaSources.add(text0);
            }
            ArrayList<MediaSource> mediaSourceList = buildTextSources();
            MediaSource videoSource = buildMediaSource(srcUri, extension);
            MediaSource mediaSource;
            if (mediaSources.size() > 1) {
                MediaSource[] textSourceArray = mediaSources.toArray(
                        new MediaSource[mediaSources.size()]
            if (mediaSourceList.size() == 0) {
                mediaSource = videoSource;
            } else {
                mediaSourceList.add(0, videoSource);
                MediaSource[] textSourceArray = mediaSourceList.toArray(
                        new MediaSource[mediaSourceList.size()]
                );
                mediaSource = new MergingMediaSource(textSourceArray);
            } else {
                mediaSource = mediaSources.get(0);
            }

            boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
@@ -288,6 +285,27 @@ class ReactExoplayerView extends FrameLayout implements
        }
    }

    private ArrayList<MediaSource> buildTextSources() {
        ArrayList<MediaSource> textSources = new ArrayList<>();
        if (textTracks == null) {
            return textSources;
        }

        for (int i = 0; i < textTracks.size(); ++i) {
            ReadableMap textTrack = textTracks.getMap(i);
            String language = textTrack.getString("language");
            String title = textTrack.hasKey("title")
                    ? textTrack.getString("title") : language + " " + i;
            Uri uri = Uri.parse(textTrack.getString("uri"));
            MediaSource textSource = buildTextSource(title, uri, textTrack.getString("type"),
                    language);
            if (textSource != null) {
                textSources.add(textSource);
            }
        }
        return textSources;
    }

    private MediaSource buildTextSource(String title, Uri uri, String mimeType, String language) {
        String sampleType;
        switch (mimeType) {
@@ -494,8 +512,31 @@ class ReactExoplayerView extends FrameLayout implements
            Format videoFormat = player.getVideoFormat();
            int width = videoFormat != null ? videoFormat.width : 0;
            int height = videoFormat != null ? videoFormat.height : 0;
            eventEmitter.load(player.getDuration(), player.getCurrentPosition(), width, height);
            eventEmitter.load(player.getDuration(), player.getCurrentPosition(), width, height,
                    getTextTrackInfo());
        }
    }

    private WritableArray getTextTrackInfo() {
        WritableArray textTracks = Arguments.createArray();

        MappingTrackSelector.MappedTrackInfo info = trackSelector.getCurrentMappedTrackInfo();
        int index = getTextTrackRendererIndex();
        if (info == null || index == C.INDEX_UNSET) {
            return textTracks;
        }

        TrackGroupArray groups = info.getTrackGroups(index);
        for (int i = 0; i < groups.length; ++i) {
             Format format = groups.get(i).getFormat(0);
             WritableMap textTrack = Arguments.createMap();
             textTrack.putInt("index", i);
             textTrack.putString("title", format.id);
             textTrack.putString("type", format.sampleMimeType);
             textTrack.putString("language", format.language);
             textTracks.pushMap(textTrack);
        }
        return textTracks;
    }

    private void onBuffering(boolean buffering) {
@@ -664,6 +705,11 @@ class ReactExoplayerView extends FrameLayout implements
        }
    }

    public void setTextTracks(ReadableArray textTracks) {
        this.textTracks = textTracks;
        reloadSource();
    }

    private void reloadSource() {
        playerNeedsSource = true;
        initializePlayer();
+8 −0
Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import android.net.Uri;
import android.text.TextUtils;

import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
@@ -28,6 +29,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
    private static final String PROP_SELECTED_TEXT_TRACK = "selectedTextTrack";
    private static final String PROP_SELECTED_TEXT_TRACK_TYPE = "type";
    private static final String PROP_SELECTED_TEXT_TRACK_VALUE = "value";
    private static final String PROP_TEXT_TRACKS = "textTracks";
    private static final String PROP_PAUSED = "paused";
    private static final String PROP_MUTED = "muted";
    private static final String PROP_VOLUME = "volume";
@@ -131,6 +133,12 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
        videoView.setSelectedTextTrack(typeString, value);
    }

    @ReactProp(name = PROP_TEXT_TRACKS)
    public void setPropTextTracks(final ReactExoplayerView videoView,
                                  @Nullable ReadableArray textTracks) {
        videoView.setTextTracks(textTracks);
    }

    @ReactProp(name = PROP_PAUSED, defaultBoolean = false)
    public void setPaused(final ReactExoplayerView videoView, final boolean paused) {
        videoView.setPausedModifier(paused);
+5 −1
Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java: 5 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ class VideoEventEmitter {
    private static final String EVENT_PROP_WIDTH = "width";
    private static final String EVENT_PROP_HEIGHT = "height";
    private static final String EVENT_PROP_ORIENTATION = "orientation";
    private static final String EVENT_PROP_TEXT_TRACKS = "textTracks";
    private static final String EVENT_PROP_HAS_AUDIO_FOCUS = "hasAudioFocus";
    private static final String EVENT_PROP_IS_BUFFERING = "isBuffering";
    private static final String EVENT_PROP_PLAYBACK_RATE = "playbackRate";
@@ -128,7 +129,8 @@ class VideoEventEmitter {
        receiveEvent(EVENT_LOAD_START, null);
    }

    void load(double duration, double currentPosition, int videoWidth, int videoHeight) {
    void load(double duration, double currentPosition, int videoWidth, int videoHeight,
              WritableArray textTracks) {
        WritableMap event = Arguments.createMap();
        event.putDouble(EVENT_PROP_DURATION, duration / 1000D);
        event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);
@@ -143,6 +145,8 @@ class VideoEventEmitter {
        }
        event.putMap(EVENT_PROP_NATURAL_SIZE, naturalSize);

        event.putArray(EVENT_PROP_TEXT_TRACKS, textTracks);

        // TODO: Actually check if you can.
        event.putBoolean(EVENT_PROP_FAST_FORWARD, true);
        event.putBoolean(EVENT_PROP_SLOW_FORWARD, true);