Commit d174b1a4 authored by Baris Sencan's avatar Baris Sencan
Browse files

[Android] Better code structure

parent 86790349
Loading
Loading
Loading
Loading
+107 −0
Changes for android/src/main/java/com/brentvatne/react/ReactVideoView.java: 107 added lines, 0 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;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.yqritc.scalablevideoview.ScalableType;
import com.yqritc.scalablevideoview.ScalableVideoView;

public class ReactVideoView extends ScalableVideoView {

    private ThemedReactContext mThemedReactContext;

    private Handler mProgressUpdateHandler = new Handler();
    private Runnable mProgressUpdateRunnable = null;

    private ScalableType mResizeMode = ScalableType.LEFT_TOP;
    private boolean mRepeat = false;
    private boolean mPaused = false;
    private boolean mMuted = false;
    private float mVolume = 1;

    public ReactVideoView(ThemedReactContext themedReactContext) {
        super(themedReactContext);

        mThemedReactContext = themedReactContext;

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

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

                if (mMediaPlayer.isPlaying()) {
                    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);
                }
                mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250);
            }
        };
        mProgressUpdateHandler.post(mProgressUpdateRunnable);
    }

    private RCTEventEmitter getEventEmitter() {
        return mThemedReactContext.getJSModule(RCTEventEmitter.class);
    }

    public void reset() {
        mMediaPlayer.reset();
    }

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

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

    public void setPausedModifier(final boolean paused) {
        mPaused = paused;

        try {
            if (!mPaused) {
                start();
            } else {
                pause();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setMutedModifier(final boolean muted) {
        mMuted = muted;

        if (mMuted) {
            setVolume(0, 0);
        } else {
            setVolume(mVolume, mVolume);
        }
    }

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

    public void applyModifiers() {
        setResizeModeModifier(mResizeMode);
        setRepeatModifier(mRepeat);
        setPausedModifier(mPaused);
        setVolumeModifier(mVolume);
    }
}
+50 −90
Changes for android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java: 50 added lines, 90 removed lines.
Original line number Diff line number Diff line
@@ -11,30 +11,28 @@ import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.yqritc.scalablevideoview.ScalableType;
import com.yqritc.scalablevideoview.ScalableVideoView;

import javax.annotation.Nullable;
import java.util.Map;

import static junit.framework.Assert.assertTrue;

public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView> {
public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {

    public static final String REACT_CLASS = "RCTVideo";
    private static final String PROP_SRC = "src";
    private static final String PROP_RESIZE_MODE = "resizeMode";
    private static final String PROP_REPEAT = "repeat";
    private static final String PROP_PAUSED = "paused";
    private static final String PROP_MUTED = "muted";
    private static final String PROP_VOLUME = "volume";

    private boolean mPrepared = false;

    private ScalableType mResizeMode = ScalableType.LEFT_TOP;
    private boolean mRepeat = false;
    private boolean mPaused = false;
    private boolean mMuted = false;
    private float mVolume = 1;
    public static final String PROP_SRC = "src";
    public static final String PROP_SRC_URI = "uri";
    public static final String PROP_SRC_TYPE = "type";
    public static final String PROP_SRC_IS_NETWORK = "isNetwork";
    public static final String PROP_RESIZE_MODE = "resizeMode";
    public static final String PROP_REPEAT = "repeat";
    public static final String PROP_PAUSED = "paused";
    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() {
@@ -42,17 +40,18 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
    }

    @Override
    protected ScalableVideoView createViewInstance(ThemedReactContext themedReactContext) {
        return new ScalableVideoView(themedReactContext);
    protected ReactVideoView createViewInstance(ThemedReactContext themedReactContext) {
        return new ReactVideoView(themedReactContext);
    }

    @Override
    @Nullable
    public Map getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.builder()
                .put("onVideoLoadStart", MapBuilder.of("registrationName", "onVideoLoadStart"))
                .put("onVideoLoad", MapBuilder.of("registrationName", "onVideoLoad"))
                .put("onVideoEnd", MapBuilder.of("registrationName", "onVideoEnd"))
                .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();
    }

@@ -60,27 +59,24 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
    @Nullable
    public Map getExportedViewConstants() {
        return MapBuilder.of(
                "ScaleNone", ScalableType.LEFT_TOP.ordinal(),
                "ScaleToFill", ScalableType.FIT_XY.ordinal(),
                "ScaleAspectFit", ScalableType.FIT_CENTER.ordinal(),
                "ScaleAspectFill", ScalableType.CENTER_CROP.ordinal()
                "ScaleNone", Integer.toString(ScalableType.LEFT_TOP.ordinal()),
                "ScaleToFill", Integer.toString(ScalableType.FIT_XY.ordinal()),
                "ScaleAspectFit", Integer.toString(ScalableType.FIT_CENTER.ordinal()),
                "ScaleAspectFill", Integer.toString(ScalableType.CENTER_CROP.ordinal())
        );
    }

    @ReactProp(name = PROP_SRC)
    public void setSrc(final ScalableVideoView videoView, @Nullable ReadableMap src) {
    public void setSrc(final ReactVideoView videoView, @Nullable ReadableMap src) {
        final ThemedReactContext themedReactContext = (ThemedReactContext) videoView.getContext();
        final RCTEventEmitter eventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class);

        try {
            final String uriString = src.getString("uri");
            final String type = src.getString("type");
            final boolean isNetwork = src.getBoolean("isNetwork");
            final String uriString = src.getString(PROP_SRC_URI);
            final String type = src.getString(PROP_SRC_TYPE);
            final boolean isNetwork = src.getBoolean(PROP_SRC_IS_NETWORK);

            if (mPrepared) {
                videoView.stop();
                mPrepared = false;
            }
            videoView.reset();

            if (isNetwork) {
                videoView.setDataSource(uriString);
@@ -90,17 +86,17 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
            }

            WritableMap writableSrc = Arguments.createMap();
            writableSrc.putString("uri", uriString);
            writableSrc.putString("type", type);
            writableSrc.putBoolean("isNetwork", isNetwork);
            writableSrc.putString(PROP_SRC_URI, uriString);
            writableSrc.putString(PROP_SRC_TYPE, type);
            writableSrc.putBoolean(PROP_SRC_IS_NETWORK, isNetwork);
            WritableMap event = Arguments.createMap();
            event.putMap("src", writableSrc);
            eventEmitter.receiveEvent(videoView.getId(), "onVideoLoadStart", event);
            event.putMap(PROP_SRC, writableSrc);
            eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD_START, event);

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

                    mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                        @Override
@@ -113,7 +109,7 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
                    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            eventEmitter.receiveEvent(videoView.getId(), "onVideoEnd", null);
                            eventEmitter.receiveEvent(videoView.getId(), EVENT_END, null);
                        }
                    });

@@ -121,9 +117,9 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
                    event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
                    event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
                    // TODO: Add canX properties.
                    eventEmitter.receiveEvent(videoView.getId(), "onVideoLoad", event);
                    eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD, event);

                    applyModifiers(videoView);
                    videoView.applyModifiers();
                }
            });
        } catch (Exception e) {
@@ -132,63 +128,27 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
    }

    @ReactProp(name = PROP_RESIZE_MODE)
    public void setResizeMode(final ScalableVideoView videoView, final int resizeModeOrdinal) {
        mResizeMode = ScalableType.values()[resizeModeOrdinal];

        if (mPrepared) {
            videoView.setScalableType(mResizeMode);
            videoView.invalidate();
        }
    public void setResizeMode(final ReactVideoView videoView, final String resizeModeOrdinalString) {
        videoView.setResizeModeModifier(ScalableType.values()[Integer.parseInt(resizeModeOrdinalString)]);
    }

    @ReactProp(name = PROP_REPEAT)
    public void setRepeat(final ScalableVideoView videoView, final boolean repeat) {
        mRepeat = repeat;

        if (mPrepared) {
            videoView.setLooping(mRepeat);
        }
    public void setRepeat(final ReactVideoView videoView, final boolean repeat) {
        videoView.setRepeatModifier(repeat);
    }

    @ReactProp(name = PROP_PAUSED)
    public void setPaused(final ScalableVideoView videoView, final boolean paused) {
        mPaused = paused;

        if (mPrepared) {
            if (!mPaused) {
                videoView.start();
            } else {
                videoView.pause();
            }
        }
    public void setPaused(final ReactVideoView videoView, final boolean paused) {
        videoView.setPausedModifier(paused);
    }

    @ReactProp(name = PROP_MUTED)
    public void setMuted(final ScalableVideoView videoView, final boolean muted) {
        mMuted = muted;

        if (mPrepared) {
            if (mMuted) {
                videoView.setVolume(0, 0);
            } else {
                videoView.setVolume(mVolume, mVolume);
            }
        }
    public void setMuted(final ReactVideoView videoView, final boolean muted) {
        videoView.setMutedModifier(muted);
    }

    @ReactProp(name = PROP_VOLUME)
    public void setVolume(final ScalableVideoView videoView, final float volume) {
        mVolume = volume;

        if (mPrepared) {
            videoView.setVolume(mVolume, mVolume);
        }
    }

    private void applyModifiers(final ScalableVideoView videoView) {
        setResizeMode(videoView, mResizeMode.ordinal());
        setRepeat(videoView, mRepeat);
        setPaused(videoView, mPaused);
        setMuted(videoView, mMuted);
    public void setVolume(final ReactVideoView videoView, final float volume) {
        videoView.setVolumeModifier(volume);
    }
}