From 417bd7a586aaf8729e79e7f6ae4ab2fa60118eba Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Wed, 3 Apr 2024 22:19:22 +0200 Subject: [PATCH 1/5] fix(ts): onPlaybackRateChangeData was not correctly typed --- examples/basic/src/VideoPlayer.tsx | 12 ++++++++++++ src/specs/VideoNativeComponent.ts | 4 ++-- src/types/events.ts | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index e719279dbe..98e1e17f02 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -36,6 +36,8 @@ import Video, { OnTextTrackDataChangedData, TextTrackType, ISO639_1, + OnPlaybackStateChangedData, + OnPlaybackRateChangeData, } from 'react-native-video'; import ToggleControl from './ToggleControl'; import MultiValueControl, { @@ -335,6 +337,14 @@ class VideoPlayer extends Component { this.channelUp(); }; + onPlaybackRateChange = (data: OnPlaybackRateChangeData) => { + console.log('onPlaybackRateChange', data); + } + + onPlaybackStateChanged = (data: OnPlaybackStateChangedData) => { + console.log('onPlaybackStateChanged', data); + } + toggleFullscreen() { this.setState({fullscreen: !this.state.fullscreen}); } @@ -805,6 +815,8 @@ class VideoPlayer extends Component { selectedAudioTrack={this.state.selectedAudioTrack} playInBackground={false} preventsDisplaySleepDuringVideoPlayback={true} + onPlaybackRateChange={this.onPlaybackRateChange} + onPlaybackStateChanged={this.onPlaybackStateChanged} /> ); diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index 11752957c7..8f8d09a12d 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -218,7 +218,7 @@ export type OnVideoTracksData = Readonly<{ }[]; }>; -export type OnPlaybackData = Readonly<{ +export type OnPlaybackRateChangeData = Readonly<{ playbackRate: Float; }>; @@ -328,7 +328,7 @@ export interface VideoNativeProps extends ViewProps { onVideoFullscreenPlayerWillDismiss?: DirectEventHandler<{}>; // ios, android onVideoFullscreenPlayerDidDismiss?: DirectEventHandler<{}>; // ios, android onReadyForDisplay?: DirectEventHandler<{}>; - onPlaybackRateChange?: DirectEventHandler; // all + onPlaybackRateChange?: DirectEventHandler; // all onVolumeChange?: DirectEventHandler; // android, ios onVideoExternalPlaybackChange?: DirectEventHandler; onGetLicense?: DirectEventHandler; diff --git a/src/types/events.ts b/src/types/events.ts index 4f9e92380b..c97cd0862b 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -7,7 +7,7 @@ import type { OnExternalPlaybackChangeData, OnLoadStartData, OnPictureInPictureStatusChangedData, - OnPlaybackData, + OnPlaybackRateChangeData, OnPlaybackStateChangedData, OnProgressData, OnSeekData, @@ -239,7 +239,7 @@ export interface ReactVideoEvents { onPictureInPictureStatusChanged?: ( e: OnPictureInPictureStatusChangedData, ) => void; //iOS - onPlaybackRateChange?: (e: OnPlaybackData) => void; //All + onPlaybackRateChange?: (e: OnPlaybackRateChangeData) => void; //All onVolumeChange?: (e: OnVolumeChangeData) => void; //Android, iOS onProgress?: (e: OnProgressData) => void; //All onReadyForDisplay?: () => void; //Android, iOS From 52b8ec197aa7aeee19fcf846e2cd4418bbd07356 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sat, 6 Apr 2024 14:22:01 +0200 Subject: [PATCH 2/5] fix: ensure tracks are well displayed in the sample --- examples/basic/src/VideoPlayer.tsx | 29 +++++++++-- ios/Video/Features/RCTPlayerOperations.swift | 51 -------------------- ios/Video/RCTVideo.swift | 2 +- 3 files changed, 27 insertions(+), 55 deletions(-) diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 98e1e17f02..0d53b10bd6 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -706,10 +706,11 @@ class VideoPlayer extends Component { AudioTrack {this.state.audioTracks?.length <= 0 ? ( - empty + empty ) : ( { console.log('on audio value change ' + itemValue); @@ -736,10 +737,11 @@ class VideoPlayer extends Component { )} TextTrack {this.state.textTracks?.length <= 0 ? ( - empty + empty ) : ( { console.log('on value change ' + itemValue); @@ -929,6 +931,13 @@ const styles = StyleSheet.create({ paddingRight: 2, lineHeight: 12, }, + pickerContainer: { + width: 100, + alignSelf: 'center', + color: 'white', + borderWidth: 1, + borderColor: 'red', + }, IndicatorStyle: { flex: 1, justifyContent: 'center', @@ -966,10 +975,24 @@ const styles = StyleSheet.create({ width: 12, }, picker: { - color: 'white', flex: 1, flexDirection: 'row', justifyContent: 'center', + width: 100, + height: 40, + }, + pickerItem: { + color: 'white', + width: 100, + height: 40, + }, + emptyPickerItem: { + color: 'white', + marginTop: 20, + marginLeft: 20, + flex: 1, + width: 100, + height: 40, }, }); diff --git a/ios/Video/Features/RCTPlayerOperations.swift b/ios/Video/Features/RCTPlayerOperations.swift index 265ab23529..3f25515923 100644 --- a/ios/Video/Features/RCTPlayerOperations.swift +++ b/ios/Video/Features/RCTPlayerOperations.swift @@ -78,57 +78,6 @@ enum RCTPlayerOperations { } } - // UNUSED - static func setStreamingText(player: AVPlayer?, criteria: SelectedTrackCriteria?) async { - let type = criteria?.type - var mediaOption: AVMediaSelectionOption! - - guard let group = await RCTVideoAssetsUtils.getMediaSelectionGroup(asset: player?.currentItem?.asset, for: .legible) else { - return - } - - if type == "disabled" { - // Do nothing. We want to ensure option is nil - } else if (type == "language") || (type == "title") { - let value = criteria?.value as? String - for i in 0 ..< group.options.count { - let currentOption: AVMediaSelectionOption! = group.options[i] - var optionValue: String! - if type == "language" { - optionValue = currentOption.extendedLanguageTag - } else { - optionValue = currentOption.commonMetadata.map(\.value)[0] as! String - } - if value == optionValue { - mediaOption = currentOption - break - } - } - // } else if ([type isEqualToString:@"default"]) { - // option = group.defaultOption; */ - } else if type == "index" { - if let value = criteria?.value, let index = value as? Int { - if group.options.count > index { - mediaOption = group.options[index] - } - } - } else { // default. invalid type or "system" - #if os(tvOS) - // Do noting. Fix for tvOS native audio menu language selector - #else - await player?.currentItem?.selectMediaOptionAutomatically(in: group) - return - #endif - } - - #if os(tvOS) - // Do noting. Fix for tvOS native audio menu language selector - #else - // If a match isn't found, option will be nil and text tracks will be disabled - await player?.currentItem?.select(mediaOption, in: group) - #endif - } - static func setMediaSelectionTrackForCharacteristic(player: AVPlayer?, characteristic: AVMediaCharacteristic, criteria: SelectedTrackCriteria?) async { let type = criteria?.type var mediaOption: AVMediaSelectionOption! diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index cb22e870f0..daa2bcb8c9 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -1471,7 +1471,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player) let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player) - self.onTextTracks?(["textTracks": textTracks]) + self.onTextTracks?(["textTracks": self._textTracks?.compactMap { $0.json } ?? textTracks.compactMap(\.json)]) self.onAudioTracks?(["audioTracks": audioTracks]) } } From af7aef5fe25e5213540f774497093b4bd57c32d8 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Thu, 25 Apr 2024 22:10:32 +0200 Subject: [PATCH 3/5] fix: fix sample style & avoid changing channel onEnd when looping is enable --- examples/basic/src/VideoPlayer.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 1caaf98a24..843cb14599 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -360,7 +360,9 @@ class VideoPlayer extends Component { }; onEnd = () => { - this.channelUp(); + if (!this.state.loop) { + this.channelUp(); + } }; onPlaybackRateChange = (data: OnPlaybackRateChangeData) => { @@ -593,8 +595,8 @@ class VideoPlayer extends Component { renderTopControl() { return ( - <> - + + {this.srcList[this.state.srcListId]?.description || 'local file'} @@ -602,12 +604,12 @@ class VideoPlayer extends Component { onPress={() => { this.toggleControls(); }}> - + {this.state.showRNVControls ? 'Hide controls' : 'Show controls'} - + ); } @@ -1032,6 +1034,9 @@ const styles = StyleSheet.create({ width: 100, height: 40, }, -}); + topControlsContainer: { + paddingTop: 30, + } + }); export default VideoPlayer; From aa615bed0a2e7ed3237d2e9e0d401d438e129d48 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Thu, 25 Apr 2024 22:30:42 +0200 Subject: [PATCH 4/5] chore: add startPosition in the sample --- examples/basic/src/VideoPlayer.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 843cb14599..4f0e76b90e 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -133,6 +133,11 @@ class VideoPlayer extends Component { description: 'sintel with subtitles', uri: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8', }, + { + description: 'sintel starts at 20sec', + uri: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8', + startPosition: 20000, + }, { description: 'BigBugBunny sideLoaded subtitles', // sideloaded subtitles wont work for streaming like HLS on ios From eb53e155e6b4ada04653f95eb2cd261e249fb035 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Thu, 25 Apr 2024 22:38:44 +0200 Subject: [PATCH 5/5] chore: update startPosition for easier testing --- examples/basic/src/VideoPlayer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 4f0e76b90e..e437b2b19e 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -136,7 +136,7 @@ class VideoPlayer extends Component { { description: 'sintel starts at 20sec', uri: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8', - startPosition: 20000, + startPosition: 50000, }, { description: 'BigBugBunny sideLoaded subtitles',