From 38d225294f7d0d499f0a4bf2770f14e14f073134 Mon Sep 17 00:00:00 2001 From: RWOverdijk Date: Tue, 25 Jul 2017 16:41:20 +0200 Subject: [PATCH 1/3] add support for onTimedMetaData for android --- .../com/brentvatne/react/ReactVideoView.java | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 94a25a0e99..62d530879f 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -4,6 +4,7 @@ import android.content.res.AssetFileDescriptor; import android.graphics.Matrix; import android.media.MediaPlayer; +import android.media.TimedMetaData; import android.net.Uri; import android.os.Handler; import android.util.Log; @@ -16,6 +17,8 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableNativeArray; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.events.RCTEventEmitter; import com.yqritc.scalablevideoview.ScalableType; @@ -24,19 +27,28 @@ import com.yqritc.scalablevideoview.Size; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import java.lang.Math; @SuppressLint("ViewConstructor") -public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnPreparedListener, MediaPlayer - .OnErrorListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener, LifecycleEventListener, MediaController.MediaPlayerControl { +public class ReactVideoView extends ScalableVideoView implements + MediaPlayer.OnPreparedListener, + MediaPlayer.OnErrorListener, + MediaPlayer.OnBufferingUpdateListener, + MediaPlayer.OnTimedMetaDataAvailableListener, + MediaPlayer.OnCompletionListener, + MediaPlayer.OnInfoListener, + LifecycleEventListener, + MediaController.MediaPlayerControl { public enum Events { EVENT_LOAD_START("onVideoLoadStart"), EVENT_LOAD("onVideoLoad"), EVENT_ERROR("onVideoError"), EVENT_PROGRESS("onVideoProgress"), + EVENT_TIMED_METADATA("onTimedMetadata"), EVENT_SEEK("onVideoSeek"), EVENT_END("onVideoEnd"), EVENT_STALLED("onPlaybackStalled"), @@ -70,6 +82,7 @@ public String toString() { public static final String EVENT_PROP_WIDTH = "width"; public static final String EVENT_PROP_HEIGHT = "height"; public static final String EVENT_PROP_ORIENTATION = "orientation"; + public static final String EVENT_PROP_METADATA = "metadata"; public static final String EVENT_PROP_ERROR = "error"; public static final String EVENT_PROP_WHAT = "what"; @@ -181,6 +194,7 @@ private void initializeMediaPlayerIfNeeded() { mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); + mMediaPlayer.setOnTimedMetaDataAvailableListener(this); mMediaPlayer.setOnInfoListener(this); } } @@ -444,6 +458,9 @@ public void run() { } }); } + + // Select track (so we can use it to listen to timed meta data updates) + mp.selectTrack(0); } @Override @@ -478,6 +495,9 @@ public boolean onInfo(MediaPlayer mp, int what, int extra) { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { + // Select track (so we can use it to listen to timed meta data updates) + mp.selectTrack(0); + mVideoBufferedDuration = (int) Math.round((double) (mVideoDuration * percent) / 100.0); } @@ -529,6 +549,30 @@ public void onCompletion(MediaPlayer mp) { mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null); } + @Override + public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data) { + WritableMap event = Arguments.createMap(); + + try { + String rawMeta = new String(data.getMetaData(), "UTF-8"); + WritableMap id3 = Arguments.createMap(); + + id3.putString("value", rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1)); + id3.putString("identifier", "id3/TDEN"); + + WritableArray metadata = new WritableNativeArray(); + + metadata.pushMap(id3); + + event.putArray(EVENT_PROP_METADATA, metadata); + event.putDouble("target", getId()); + } catch(UnsupportedEncodingException e) { + e.printStackTrace(); + } + + mEventEmitter.receiveEvent(getId(), Events.EVENT_TIMED_METADATA.toString(), event); + } + @Override protected void onDetachedFromWindow() { From aa89683785999f978fa7d60ca1f9a61b6b13f2d0 Mon Sep 17 00:00:00 2001 From: RWOverdijk Date: Tue, 25 Jul 2017 16:53:04 +0200 Subject: [PATCH 2/3] move prop keys for metadata to constants --- .../main/java/com/brentvatne/react/ReactVideoView.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 62d530879f..dc51346933 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -83,6 +83,9 @@ public String toString() { public static final String EVENT_PROP_HEIGHT = "height"; public static final String EVENT_PROP_ORIENTATION = "orientation"; public static final String EVENT_PROP_METADATA = "metadata"; + public static final String EVENT_PROP_TARGET = "target"; + public static final String EVENT_PROP_METADATA_IDENTIFIER = "identifier"; + public static final String EVENT_PROP_METADATA_VALUE = "value"; public static final String EVENT_PROP_ERROR = "error"; public static final String EVENT_PROP_WHAT = "what"; @@ -557,15 +560,15 @@ public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data) { String rawMeta = new String(data.getMetaData(), "UTF-8"); WritableMap id3 = Arguments.createMap(); - id3.putString("value", rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1)); - id3.putString("identifier", "id3/TDEN"); + id3.putString(EVENT_PROP_METADATA_VALUE, rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1)); + id3.putString(EVENT_PROP_METADATA_IDENTIFIER, "id3/TDEN"); WritableArray metadata = new WritableNativeArray(); metadata.pushMap(id3); event.putArray(EVENT_PROP_METADATA, metadata); - event.putDouble("target", getId()); + event.putDouble(EVENT_PROP_TARGET, getId()); } catch(UnsupportedEncodingException e) { e.printStackTrace(); } From 70d863e3d00b1f66fc8b25f2f4e924befced2815 Mon Sep 17 00:00:00 2001 From: Hampton Maxwell Date: Mon, 25 Jun 2018 14:25:12 -0700 Subject: [PATCH 3/3] Allow timed metadata to compile on older SDKs --- .../com/brentvatne/react/ReactVideoView.java | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index dc51346933..daacd025ea 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -37,7 +37,6 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener, - MediaPlayer.OnTimedMetaDataAvailableListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener, LifecycleEventListener, @@ -197,8 +196,10 @@ private void initializeMediaPlayerIfNeeded() { mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); - mMediaPlayer.setOnTimedMetaDataAvailableListener(this); mMediaPlayer.setOnInfoListener(this); + if (Build.VERSION.SDK_INT >= 23) { + mMediaPlayer.setOnTimedMetaDataAvailableListener(new TimedMetaDataAvailableListener()); + } } } @@ -551,29 +552,34 @@ public void onCompletion(MediaPlayer mp) { isCompleted = true; mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null); } + + // This is not fully tested and does not work for all forms of timed metadata + @TargetApi(23) // 6.0 + public class TimedMetaDataAvailableListener + implements MediaPlayer.OnTimedMetaDataAvailableListener + { + public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data) { + WritableMap event = Arguments.createMap(); - @Override - public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data) { - WritableMap event = Arguments.createMap(); + try { + String rawMeta = new String(data.getMetaData(), "UTF-8"); + WritableMap id3 = Arguments.createMap(); - try { - String rawMeta = new String(data.getMetaData(), "UTF-8"); - WritableMap id3 = Arguments.createMap(); + id3.putString(EVENT_PROP_METADATA_VALUE, rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1)); + id3.putString(EVENT_PROP_METADATA_IDENTIFIER, "id3/TDEN"); - id3.putString(EVENT_PROP_METADATA_VALUE, rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1)); - id3.putString(EVENT_PROP_METADATA_IDENTIFIER, "id3/TDEN"); + WritableArray metadata = new WritableNativeArray(); - WritableArray metadata = new WritableNativeArray(); + metadata.pushMap(id3); - metadata.pushMap(id3); + event.putArray(EVENT_PROP_METADATA, metadata); + event.putDouble(EVENT_PROP_TARGET, getId()); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } - event.putArray(EVENT_PROP_METADATA, metadata); - event.putDouble(EVENT_PROP_TARGET, getId()); - } catch(UnsupportedEncodingException e) { - e.printStackTrace(); + mEventEmitter.receiveEvent(getId(), Events.EVENT_TIMED_METADATA.toString(), event); } - - mEventEmitter.receiveEvent(getId(), Events.EVENT_TIMED_METADATA.toString(), event); } @Override