diff --git a/API.md b/API.md
index 9ac52616..e15ed199 100644
--- a/API.md
+++ b/API.md
@@ -316,6 +316,7 @@ var styles = StyleSheet.create({
| Name |Plateforms Support |
|--|--|
|[onAudioBecomingNoisy](#onaudiobecomingnoisy)|Android, iOS|
+|[onAudioTracks](#onAudioTracks)|Android|
|[onBandwidthUpdate](#onbandwidthupdate)|Android|
|[onBuffer](#onbuffer)|Android, iOS|
|[onEnd](#onend)|All|
@@ -333,6 +334,8 @@ var styles = StyleSheet.create({
|[onSeek](#onseek)|Android, iOS, Windows UWP|
|[onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop)|iOS|
|[onTimedMetadata](#ontimedmetadata)|Android, iOS|
+|[onTextTracks](#onTextTracks)|Android|
+|[onVideoTracks](#onVideoTracks)|Android|
### Methods
@@ -652,6 +655,34 @@ Determine whether to repeat the video when the end is reached
Platforms: all
+
+#### onAudioTracks
+Callback function that is called when audio tracks change
+
+Payload:
+
+Property | Type | Description
+--- | --- | ---
+index | number | Internal track ID
+title | string | Descriptive name for the track
+language | string | 2 letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language
+bitrate | number | bitrate of track
+type | string | Mime type of track
+selected | boolean | true if track is playing
+
+Example:
+```
+{
+ audioTracks: [
+ { language: 'es', title: 'Spanish', type: 'audio/mpeg', index: 0, selected: true },
+ { language: 'en', title: 'English', type: 'audio/mpeg', index: 1 }
+ ],
+}
+```
+
+
+Platforms: Android
+
#### reportBandwidth
Determine whether to generate onBandwidthUpdate events. This is needed due to the high frequency of these events on ExoPlayer.
@@ -1228,6 +1259,69 @@ Example:
Platforms: Android, iOS
+#### onTextTracks
+Callback function that is called when text tracks change
+
+Payload:
+
+Property | Type | Description
+--- | --- | ---
+index | number | Internal track ID
+title | string | Descriptive name for the track
+language | string | 2 letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language
+type | string | Mime type of the track
* TextTrackType.SRT - SubRip (.srt)
* TextTrackType.TTML - TTML (.ttml)
* TextTrackType.VTT - WebVTT (.vtt)
iOS only supports VTT, Android supports all 3
+selected | boolean | true if track is playing
+
+
+Example:
+```
+{
+ textTracks: [
+ {
+ index: 0,
+ title: 'Any Time You Like',
+ type: 'srt',
+ selected: true
+ }
+ ]
+}
+```
+
+Platforms: Android
+
+#### onVideoTracks
+Callback function that is called when video tracks change
+
+Payload:
+
+Property | Type | Description
+--- | --- | ---
+trackId | number | Internal track ID
+codecs | string | MimeType of codec used for this track
+width | number | Track width
+height | number | Track height
+bitrate | number | Bitrate in bps
+selected | boolean | true if track is selected for playing
+
+
+Example:
+```
+{
+ videoTracks: [
+ {
+ trackId: 0,
+ codecs: 'video/mp4',
+ width: 1920,
+ height: 1080,
+ bitrate: 10000,
+ selected: true
+ }
+ ]
+}
+```
+
+Platforms: Android
+
### Methods
Methods operate on a ref to the Video element. You can create a ref using code like:
```
diff --git a/Video.js b/Video.js
index dad262b9..a0f47867 100644
--- a/Video.js
+++ b/Video.js
@@ -116,6 +116,24 @@ export default class Video extends Component {
}
};
+ _onAudioTracks = (event) => {
+ if (this.props.onAudioTracks) {
+ this.props.onAudioTracks(event.nativeEvent);
+ }
+ };
+
+ _onTextTracks = (event) => {
+ if (this.props.onTextTracks) {
+ this.props.onTextTracks(event.nativeEvent);
+ }
+ };
+
+ _onVideoTracks = (event) => {
+ if (this.props.onVideoTracks) {
+ this.props.onVideoTracks(event.nativeEvent);
+ }
+ };
+
_onError = (event) => {
if (this.props.onError) {
this.props.onError(event.nativeEvent);
@@ -316,6 +334,9 @@ export default class Video extends Component {
onVideoLoadStart: this._onLoadStart,
onVideoPlaybackStateChanged: this._onPlaybackStateChanged,
onVideoLoad: this._onLoad,
+ onAudioTracks: this._onAudioTracks,
+ onTextTracks: this._onTextTracks,
+ onVideoTracks: this._onVideoTracks,
onVideoError: this._onError,
onVideoProgress: this._onProgress,
onVideoSeek: this._onSeek,
@@ -495,6 +516,9 @@ Video.propTypes = {
onLoadStart: PropTypes.func,
onPlaybackStateChanged: PropTypes.func,
onLoad: PropTypes.func,
+ onAudioTracks: PropTypes.func,
+ onTextTracks: PropTypes.func,
+ onVideoTracks: PropTypes.func,
onBuffer: PropTypes.func,
onError: PropTypes.func,
onProgress: PropTypes.func,
diff --git a/android/src/main/java/com/brentvatne/common/Track.java b/android/src/main/java/com/brentvatne/common/Track.java
new file mode 100644
index 00000000..198f9ec7
--- /dev/null
+++ b/android/src/main/java/com/brentvatne/common/Track.java
@@ -0,0 +1,13 @@
+package com.brentvatne.common;
+import android.net.Uri;
+
+public class Track
+{
+ public String m_title;
+ public Uri m_uri;
+ public String m_mimeType;
+ public String m_language;
+ public boolean m_isSelected;
+ public int m_bitrate;
+ public int m_index;
+}
diff --git a/android/src/main/java/com/brentvatne/common/VideoTrack.java b/android/src/main/java/com/brentvatne/common/VideoTrack.java
new file mode 100644
index 00000000..6eccd983
--- /dev/null
+++ b/android/src/main/java/com/brentvatne/common/VideoTrack.java
@@ -0,0 +1,12 @@
+package com.brentvatne.common;
+
+public class VideoTrack
+{
+ public int m_width = 0;
+ public int m_height = 0;
+ public int m_bitrate = 0;
+ public String m_codecs = "";
+ public int m_id = -1;
+ public String m_trackId = "";
+ public boolean m_isSelected = false;
+}
diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
index 43d4a6ee..1ba9bb6f 100644
--- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
+++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
@@ -17,24 +17,21 @@ import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
+import androidx.annotation.WorkerThread;
+
+import com.brentvatne.common.Track;
+import com.brentvatne.common.VideoTrack;
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.facebook.react.util.RNLog;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
-import com.google.android.exoplayer2.ExoPlaybackException;
-import com.google.android.exoplayer2.drm.MediaDrmCallbackException;
-import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
@@ -47,16 +44,12 @@ import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManagerProvider;
-import com.google.android.exoplayer2.drm.ExoMediaDrm;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
-import com.google.android.exoplayer2.drm.MediaDrmCallbackException;
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
-import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
import com.google.android.exoplayer2.metadata.Metadata;
-import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
@@ -72,6 +65,7 @@ import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
+import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
import com.google.android.exoplayer2.ui.PlayerControlView;
@@ -80,7 +74,6 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.HttpDataSource;
-import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.source.dash.DashUtil;
@@ -88,7 +81,6 @@ import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.Representation;
-import com.google.android.exoplayer2.source.dash.manifest.Descriptor;
import java.net.CookieHandler;
import java.net.CookieManager;
@@ -98,9 +90,6 @@ import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.List;
import java.lang.Thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -1043,25 +1032,42 @@ class ReactExoplayerView extends FrameLayout implements
// Properties that must be accessed on the main thread
long duration = player.getDuration();
long currentPosition = player.getCurrentPosition();
- WritableArray audioTrackInfo = getAudioTrackInfo();
- WritableArray textTrackInfo = getTextTrackInfo();
- int trackRendererIndex = getTrackRendererIndex(C.TRACK_TYPE_VIDEO);
+ ArrayList