Loading Video.js +7 −0 Changes for Video.js: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -274,6 +274,13 @@ Video.propTypes = { poster: PropTypes.string, posterResizeMode: Image.propTypes.resizeMode, repeat: PropTypes.bool, selectedTextTrack: PropTypes.shape({ type: PropTypes.string.isRequired, value: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]) }), paused: PropTypes.bool, muted: PropTypes.bool, volume: PropTypes.number, Loading android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +62 −1 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java: 62 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import android.widget.FrameLayout; import com.brentvatne.react.R; import com.brentvatne.receiver.AudioBecomingNoisyReceiver; import com.brentvatne.receiver.BecomingNoisyListener; import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.uimanager.ThemedReactContext; import com.google.android.exoplayer2.C; Loading Loading @@ -45,6 +46,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.FixedTrackSelection; import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; Loading Loading @@ -535,7 +537,8 @@ class ReactExoplayerView extends FrameLayout implements decoderInitializationException.decoderName); } } } else if (e.type == ExoPlaybackException.TYPE_SOURCE) { } else if (e.type == ExoPlaybackException.TYPE_SOURCE) { ex = e.getSourceException(); errorString = getResources().getString(R.string.unrecognized_media_format); } Loading Loading @@ -565,6 +568,16 @@ class ReactExoplayerView extends FrameLayout implements return false; } public int getTextTrackRendererIndex() { int rendererCount = player.getRendererCount(); for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { if (player.getRendererType(rendererIndex) == C.TRACK_TYPE_TEXT) { return rendererIndex; } } return C.INDEX_UNSET; } @Override public void onMetadata(Metadata metadata) { eventEmitter.timedMetadata(metadata); Loading Loading @@ -626,6 +639,54 @@ class ReactExoplayerView extends FrameLayout implements this.repeat = repeat; } public void setSelectedTextTrack(String type, Dynamic value) { int index = getTextTrackRendererIndex(); if (index == C.INDEX_UNSET) { return; } MappingTrackSelector.MappedTrackInfo info = trackSelector.getCurrentMappedTrackInfo(); if (info == null) { return; } TrackGroupArray groups = info.getTrackGroups(index); int trackIndex = C.INDEX_UNSET; if (TextUtils.isEmpty(type)) { // Do nothing } else if (type.equals("language")) { for (int i = 0; i < groups.length; ++i) { Format format = groups.get(i).getFormat(0); if (format.language != null && format.language.equals(value.asString())) { trackIndex = i; break; } } } else if (type.equals("title")) { for (int i = 0; i < groups.length; ++i) { Format format = groups.get(i).getFormat(0); if (format.id != null && format.id.equals(value.asString())) { trackIndex = i; break; } } } else if (type.equals("index")) { trackIndex = value.asInt(); } else { // default. invalid type or "system" trackSelector.clearSelectionOverrides(index); return; } if (trackIndex == C.INDEX_UNSET) { trackSelector.clearSelectionOverrides(trackIndex); return; } MappingTrackSelector.SelectionOverride override = new MappingTrackSelector.SelectionOverride( new FixedTrackSelection.Factory(), trackIndex, 0); trackSelector.setSelectionOverride(index, groups, override); } public void setPausedModifier(boolean paused) { isPaused = paused; if (player != null) { Loading android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java +14 −0 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.content.Context; import android.net.Uri; import android.text.TextUtils; import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.ThemedReactContext; Loading @@ -24,6 +25,9 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi private static final String PROP_SRC_TYPE = "type"; private static final String PROP_RESIZE_MODE = "resizeMode"; private static final String PROP_REPEAT = "repeat"; 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_PAUSED = "paused"; private static final String PROP_MUTED = "muted"; private static final String PROP_VOLUME = "volume"; Loading Loading @@ -116,6 +120,16 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi videoView.setRepeatModifier(repeat); } @ReactProp(name = PROP_SELECTED_TEXT_TRACK) public void setSelectedTextTrack(final ReactExoplayerView videoView, @Nullable ReadableMap selectedTextTrack) { String typeString = selectedTextTrack.hasKey(PROP_SELECTED_TEXT_TRACK_TYPE) ? selectedTextTrack.getString(PROP_SELECTED_TEXT_TRACK_TYPE) : null; Dynamic value = selectedTextTrack.hasKey(PROP_SELECTED_TEXT_TRACK_VALUE) ? selectedTextTrack.getDynamic(PROP_SELECTED_TEXT_TRACK_VALUE) : null; videoView.setSelectedTextTrack(typeString, value); } @ReactProp(name = PROP_PAUSED, defaultBoolean = false) public void setPaused(final ReactExoplayerView videoView, final boolean paused) { videoView.setPausedModifier(paused); Loading ios/RCTVideo.m +46 −0 Changes for ios/RCTVideo.m: 46 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ static NSString *const timedMetadata = @"timedMetadata"; BOOL _muted; BOOL _paused; BOOL _repeat; NSDictionary * _selectedTextTrack; BOOL _playbackStalled; BOOL _playInBackground; BOOL _playWhenInactive; Loading Loading @@ -625,6 +626,7 @@ static NSString *const timedMetadata = @"timedMetadata"; [_player setMuted:NO]; } [self setSelectedTextTrack:_selectedTextTrack]; [self setResizeMode:_resizeMode]; [self setRepeat:_repeat]; [self setPaused:_paused]; Loading @@ -635,6 +637,50 @@ static NSString *const timedMetadata = @"timedMetadata"; _repeat = repeat; } - (void)setSelectedTextTrack:(NSDictionary *)selectedTextTrack { _selectedTextTrack = selectedTextTrack; NSString *type = selectedTextTrack[@"type"]; AVMediaSelectionGroup *group = [_player.currentItem.asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible]; AVMediaSelectionOption *option; if ([type isEqualToString:@"disabled"]) { // Do nothing. We want to ensure option is nil } else if ([type isEqualToString:@"language"] || [type isEqualToString:@"title"]) { NSString *value = selectedTextTrack[@"value"]; for (int i = 0; i < group.options.count; ++i) { AVMediaSelectionOption *currentOption = [group.options objectAtIndex:i]; NSString *optionValue; if ([type isEqualToString:@"language"]) { optionValue = [currentOption extendedLanguageTag]; } else { optionValue = [[[currentOption commonMetadata] valueForKey:@"value"] objectAtIndex:0]; } if ([value isEqualToString:optionValue]) { option = currentOption; break; } } } else if ([type isEqualToString:@"index"]) { if ([selectedTextTrack[@"value"] isKindOfClass:[NSNumber class]]) { int index = [selectedTextTrack[@"value"] intValue]; if (group.options.count > index) { option = [group.options objectAtIndex:index]; } } } else { // default. invalid type or "system" // _player.appliesMediaSelectionCriteriaAutomatically = YES; return; } // If a match isn't found, option will be nil and text tracks will be disabled // _player.appliesMediaSelectionCriteriaAutomatically = NO; [_player.currentItem selectMediaOption:option inMediaSelectionGroup:group]; } - (BOOL)getFullscreen { return _fullscreenPlayerPresented; Loading ios/RCTVideoManager.m +1 −0 Changes for ios/RCTVideoManager.m: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ RCT_EXPORT_MODULE(); RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString); RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL); RCT_EXPORT_VIEW_PROPERTY(selectedTextTrack, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(paused, BOOL); RCT_EXPORT_VIEW_PROPERTY(muted, BOOL); RCT_EXPORT_VIEW_PROPERTY(controls, BOOL); Loading Loading
Video.js +7 −0 Changes for Video.js: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -274,6 +274,13 @@ Video.propTypes = { poster: PropTypes.string, posterResizeMode: Image.propTypes.resizeMode, repeat: PropTypes.bool, selectedTextTrack: PropTypes.shape({ type: PropTypes.string.isRequired, value: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]) }), paused: PropTypes.bool, muted: PropTypes.bool, volume: PropTypes.number, Loading
android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +62 −1 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java: 62 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import android.widget.FrameLayout; import com.brentvatne.react.R; import com.brentvatne.receiver.AudioBecomingNoisyReceiver; import com.brentvatne.receiver.BecomingNoisyListener; import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.uimanager.ThemedReactContext; import com.google.android.exoplayer2.C; Loading Loading @@ -45,6 +46,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.FixedTrackSelection; import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; Loading Loading @@ -535,7 +537,8 @@ class ReactExoplayerView extends FrameLayout implements decoderInitializationException.decoderName); } } } else if (e.type == ExoPlaybackException.TYPE_SOURCE) { } else if (e.type == ExoPlaybackException.TYPE_SOURCE) { ex = e.getSourceException(); errorString = getResources().getString(R.string.unrecognized_media_format); } Loading Loading @@ -565,6 +568,16 @@ class ReactExoplayerView extends FrameLayout implements return false; } public int getTextTrackRendererIndex() { int rendererCount = player.getRendererCount(); for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { if (player.getRendererType(rendererIndex) == C.TRACK_TYPE_TEXT) { return rendererIndex; } } return C.INDEX_UNSET; } @Override public void onMetadata(Metadata metadata) { eventEmitter.timedMetadata(metadata); Loading Loading @@ -626,6 +639,54 @@ class ReactExoplayerView extends FrameLayout implements this.repeat = repeat; } public void setSelectedTextTrack(String type, Dynamic value) { int index = getTextTrackRendererIndex(); if (index == C.INDEX_UNSET) { return; } MappingTrackSelector.MappedTrackInfo info = trackSelector.getCurrentMappedTrackInfo(); if (info == null) { return; } TrackGroupArray groups = info.getTrackGroups(index); int trackIndex = C.INDEX_UNSET; if (TextUtils.isEmpty(type)) { // Do nothing } else if (type.equals("language")) { for (int i = 0; i < groups.length; ++i) { Format format = groups.get(i).getFormat(0); if (format.language != null && format.language.equals(value.asString())) { trackIndex = i; break; } } } else if (type.equals("title")) { for (int i = 0; i < groups.length; ++i) { Format format = groups.get(i).getFormat(0); if (format.id != null && format.id.equals(value.asString())) { trackIndex = i; break; } } } else if (type.equals("index")) { trackIndex = value.asInt(); } else { // default. invalid type or "system" trackSelector.clearSelectionOverrides(index); return; } if (trackIndex == C.INDEX_UNSET) { trackSelector.clearSelectionOverrides(trackIndex); return; } MappingTrackSelector.SelectionOverride override = new MappingTrackSelector.SelectionOverride( new FixedTrackSelection.Factory(), trackIndex, 0); trackSelector.setSelectionOverride(index, groups, override); } public void setPausedModifier(boolean paused) { isPaused = paused; if (player != null) { Loading
android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java +14 −0 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.content.Context; import android.net.Uri; import android.text.TextUtils; import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.ThemedReactContext; Loading @@ -24,6 +25,9 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi private static final String PROP_SRC_TYPE = "type"; private static final String PROP_RESIZE_MODE = "resizeMode"; private static final String PROP_REPEAT = "repeat"; 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_PAUSED = "paused"; private static final String PROP_MUTED = "muted"; private static final String PROP_VOLUME = "volume"; Loading Loading @@ -116,6 +120,16 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi videoView.setRepeatModifier(repeat); } @ReactProp(name = PROP_SELECTED_TEXT_TRACK) public void setSelectedTextTrack(final ReactExoplayerView videoView, @Nullable ReadableMap selectedTextTrack) { String typeString = selectedTextTrack.hasKey(PROP_SELECTED_TEXT_TRACK_TYPE) ? selectedTextTrack.getString(PROP_SELECTED_TEXT_TRACK_TYPE) : null; Dynamic value = selectedTextTrack.hasKey(PROP_SELECTED_TEXT_TRACK_VALUE) ? selectedTextTrack.getDynamic(PROP_SELECTED_TEXT_TRACK_VALUE) : null; videoView.setSelectedTextTrack(typeString, value); } @ReactProp(name = PROP_PAUSED, defaultBoolean = false) public void setPaused(final ReactExoplayerView videoView, final boolean paused) { videoView.setPausedModifier(paused); Loading
ios/RCTVideo.m +46 −0 Changes for ios/RCTVideo.m: 46 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ static NSString *const timedMetadata = @"timedMetadata"; BOOL _muted; BOOL _paused; BOOL _repeat; NSDictionary * _selectedTextTrack; BOOL _playbackStalled; BOOL _playInBackground; BOOL _playWhenInactive; Loading Loading @@ -625,6 +626,7 @@ static NSString *const timedMetadata = @"timedMetadata"; [_player setMuted:NO]; } [self setSelectedTextTrack:_selectedTextTrack]; [self setResizeMode:_resizeMode]; [self setRepeat:_repeat]; [self setPaused:_paused]; Loading @@ -635,6 +637,50 @@ static NSString *const timedMetadata = @"timedMetadata"; _repeat = repeat; } - (void)setSelectedTextTrack:(NSDictionary *)selectedTextTrack { _selectedTextTrack = selectedTextTrack; NSString *type = selectedTextTrack[@"type"]; AVMediaSelectionGroup *group = [_player.currentItem.asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible]; AVMediaSelectionOption *option; if ([type isEqualToString:@"disabled"]) { // Do nothing. We want to ensure option is nil } else if ([type isEqualToString:@"language"] || [type isEqualToString:@"title"]) { NSString *value = selectedTextTrack[@"value"]; for (int i = 0; i < group.options.count; ++i) { AVMediaSelectionOption *currentOption = [group.options objectAtIndex:i]; NSString *optionValue; if ([type isEqualToString:@"language"]) { optionValue = [currentOption extendedLanguageTag]; } else { optionValue = [[[currentOption commonMetadata] valueForKey:@"value"] objectAtIndex:0]; } if ([value isEqualToString:optionValue]) { option = currentOption; break; } } } else if ([type isEqualToString:@"index"]) { if ([selectedTextTrack[@"value"] isKindOfClass:[NSNumber class]]) { int index = [selectedTextTrack[@"value"] intValue]; if (group.options.count > index) { option = [group.options objectAtIndex:index]; } } } else { // default. invalid type or "system" // _player.appliesMediaSelectionCriteriaAutomatically = YES; return; } // If a match isn't found, option will be nil and text tracks will be disabled // _player.appliesMediaSelectionCriteriaAutomatically = NO; [_player.currentItem selectMediaOption:option inMediaSelectionGroup:group]; } - (BOOL)getFullscreen { return _fullscreenPlayerPresented; Loading
ios/RCTVideoManager.m +1 −0 Changes for ios/RCTVideoManager.m: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ RCT_EXPORT_MODULE(); RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString); RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL); RCT_EXPORT_VIEW_PROPERTY(selectedTextTrack, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(paused, BOOL); RCT_EXPORT_VIEW_PROPERTY(muted, BOOL); RCT_EXPORT_VIEW_PROPERTY(controls, BOOL); Loading