Commit 9e9e45c1 authored by Baris Sencan's avatar Baris Sencan
Browse files

[Android] Move events inside RCTVideoView

parent 125b99de
Loading
Loading
Loading
Loading
+86 −11
Changes for android/src/main/java/com/brentvatne/react/ReactVideoView.java: 86 added lines, 11 removed lines.
Original line number Diff line number Diff line
package com.brentvatne.react;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Handler;
import com.facebook.react.bridge.Arguments;
@@ -10,9 +9,31 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.yqritc.scalablevideoview.ScalableType;
import com.yqritc.scalablevideoview.ScalableVideoView;

public class ReactVideoView extends ScalableVideoView {
public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnPreparedListener, MediaPlayer
        .OnErrorListener, MediaPlayer.OnCompletionListener {

    public enum Events {
        EVENT_LOAD_START("onVideoLoadStart"),
        EVENT_LOAD("onVideoLoad"),
        EVENT_ERROR("onVideoError"),
        EVENT_PROGRESS("onVideoProgress"),
        EVENT_SEEK("onVideoSeek"),
        EVENT_END("onVideoEnd");

        private final String mName;

        Events(final String name) {
            mName = name;
        }

        @Override
        public String toString() {
            return mName;
        }
    }

    private ThemedReactContext mThemedReactContext;
    private RCTEventEmitter mEventEmitter;

    private Handler mProgressUpdateHandler = new Handler();
    private Runnable mProgressUpdateRunnable = null;
@@ -27,22 +48,26 @@ public class ReactVideoView extends ScalableVideoView {
        super(themedReactContext);

        mThemedReactContext = themedReactContext;
        mEventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class);

        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnVideoSizeChangedListener(this);
        initializeMediaPlayerIfNeeded();
        setSurfaceTextureListener(this);

        final MediaPlayer mediaPlayer = mMediaPlayer;

        mProgressUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                final RCTEventEmitter eventEmitter = getEventEmitter();

                if (mMediaPlayer.isPlaying()) {
                try {
                    WritableMap event = Arguments.createMap();
                    // TODO: Other event properties.
                    event.putDouble("currentTime", (double) mMediaPlayer.getCurrentPosition() / (double) 1000);
                    event.putDouble("duration", (double) mMediaPlayer.getDuration() / (double) 1000);
                    eventEmitter.receiveEvent(getId(), ReactVideoViewManager.EVENT_PROGRESS, event);
                    event.putDouble("currentTime", (double) mediaPlayer.getCurrentPosition() / (double) 1000);
                    event.putDouble("duration", (double) mediaPlayer.getDuration() / (double) 1000);
                    event.putDouble("playableDuration", (double) mediaPlayer.getDuration() / (double) 1000);
                    mEventEmitter.receiveEvent(getId(), Events.EVENT_PROGRESS.toString(), event);
                } catch (Exception e) {
                    // Do nothing.
                }
                mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250);
            }
@@ -50,8 +75,14 @@ public class ReactVideoView extends ScalableVideoView {
        mProgressUpdateHandler.post(mProgressUpdateRunnable);
    }

    private RCTEventEmitter getEventEmitter() {
        return mThemedReactContext.getJSModule(RCTEventEmitter.class);
    private void initializeMediaPlayerIfNeeded() {
        if (mMediaPlayer == null) {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setOnErrorListener(this);
            mMediaPlayer.setOnPreparedListener(this);
        }
    }

    public void reset() {
@@ -60,12 +91,14 @@ public class ReactVideoView extends ScalableVideoView {

    public void setResizeModeModifier(final ScalableType resizeMode) {
        mResizeMode = resizeMode;
        initializeMediaPlayerIfNeeded();
        setScalableType(resizeMode);
        invalidate();
    }

    public void setRepeatModifier(final boolean repeat) {
        mRepeat = repeat;
        initializeMediaPlayerIfNeeded();
        setLooping(repeat);
    }

@@ -73,6 +106,8 @@ public class ReactVideoView extends ScalableVideoView {
        mPaused = paused;

        try {
            initializeMediaPlayerIfNeeded();

            if (!mPaused) {
                start();
            } else {
@@ -86,6 +121,8 @@ public class ReactVideoView extends ScalableVideoView {
    public void setMutedModifier(final boolean muted) {
        mMuted = muted;

        initializeMediaPlayerIfNeeded();

        if (mMuted) {
            setVolume(0, 0);
        } else {
@@ -95,6 +132,7 @@ public class ReactVideoView extends ScalableVideoView {

    public void setVolumeModifier(final float volume) {
        mVolume = volume;
        initializeMediaPlayerIfNeeded();
        setMutedModifier(mMuted);
    }

@@ -104,4 +142,41 @@ public class ReactVideoView extends ScalableVideoView {
        setPausedModifier(mPaused);
        setVolumeModifier(mVolume);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        WritableMap event = Arguments.createMap();
        event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
        event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
        // TODO: Add canX properties.
        mEventEmitter.receiveEvent(getId(), Events.EVENT_LOAD.toString(), event);

        applyModifiers();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        WritableMap error = Arguments.createMap();
        error.putInt("what", what);
        error.putInt("extra", extra);
        WritableMap event = Arguments.createMap();
        event.putMap("error", error);
        mEventEmitter.receiveEvent(getId(), Events.EVENT_ERROR.toString(), event);
        return true;
    }

    @Override
    public void seekTo(int msec) {
        WritableMap event = Arguments.createMap();
        event.putDouble("currentTime", (double) getCurrentPosition() / (double) 1000);
        event.putDouble("seekTime", (double) msec / (double) 1000);
        mEventEmitter.receiveEvent(getId(), Events.EVENT_SEEK.toString(), event);

        super.seekTo(msec);
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null);
    }
}
+9 −43
Changes for android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java: 9 added lines, 43 removed lines.
Original line number Diff line number Diff line
package com.brentvatne.react;

import android.content.Context;
import android.media.MediaPlayer;
import com.brentvatne.react.ReactVideoView.Events;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
@@ -29,11 +29,6 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
    public static final String PROP_MUTED = "muted";
    public static final String PROP_VOLUME = "volume";

    public static final String EVENT_LOAD_START = "onVideoLoadStart";
    public static final String EVENT_LOAD = "onVideoLoad";
    public static final String EVENT_PROGRESS = "onVideoProgress";
    public static final String EVENT_END = "onVideoEnd";

    @Override
    public String getName() {
        return REACT_CLASS;
@@ -47,12 +42,11 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
    @Override
    @Nullable
    public Map getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.builder()
                .put(EVENT_LOAD_START, MapBuilder.of("registrationName", EVENT_LOAD_START))
                .put(EVENT_LOAD, MapBuilder.of("registrationName", EVENT_LOAD))
                .put(EVENT_PROGRESS, MapBuilder.of("registrationName", EVENT_PROGRESS))
                .put(EVENT_END, MapBuilder.of("registrationName", EVENT_END))
                .build();
        MapBuilder.Builder builder = MapBuilder.builder();
        for (Events event : Events.values()) {
            builder.put(event.toString(), MapBuilder.of("registrationName", event.toString()));
        }
        return builder.build();
    }

    @Override
@@ -91,39 +85,11 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
            writableSrc.putBoolean(PROP_SRC_IS_NETWORK, isNetwork);
            WritableMap event = Arguments.createMap();
            event.putMap(PROP_SRC, writableSrc);
            eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD_START, event);

            videoView.prepare(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(final MediaPlayer mp) {
                    mp.setScreenOnWhilePlaying(true);

                    mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                        @Override
                        public boolean onError(MediaPlayer mp, int what, int extra) {
                            // TODO: onVideoError
                            return false;
                        }
                    });
            eventEmitter.receiveEvent(videoView.getId(), Events.EVENT_LOAD_START.toString(), event);

                    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            eventEmitter.receiveEvent(videoView.getId(), EVENT_END, null);
                        }
                    });

                    WritableMap event = Arguments.createMap();
                    event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
                    event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
                    // TODO: Add canX properties.
                    eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD, event);

                    videoView.applyModifiers();
                }
            });
            videoView.prepare();
        } catch (Exception e) {
            // TODO: onVideoError
            e.printStackTrace();
        }
    }