Compare commits

...

61 Commits

Author SHA1 Message Date
ff0f288636 Merge remote-tracking branch 'origin/master' into ivan/merging-shaka-hls 2024-12-02 22:57:41 -07:00
d7977241c9 Account for crop in progress 2024-10-18 03:25:50 -06:00
921ead0f05 Timeout actions 2024-10-17 19:21:06 -06:00
20397d32e6 More logging 2024-10-17 19:11:22 -06:00
e3900e794d What is going on 2024-10-17 19:07:39 -06:00
4dc7bf465f Typescript 2024-10-17 18:59:42 -06:00
e5f182cda9 Use an async queue 2024-10-17 18:56:38 -06:00
9138c3249d Try to fix double load 2024-10-17 18:34:34 -06:00
7a1d0e8b10 Try to fix source quality issue 2024-10-17 18:28:16 -06:00
9cbba8f95e Typescript again 2024-10-17 18:22:26 -06:00
2cfb26d51f Typescript 2024-10-17 18:20:28 -06:00
4f18e9b238 Fix never ending loading, try to respect crops 2024-10-17 18:19:05 -06:00
bd64379837 Merge pull request 'Fix android build' (#7) from volodymyr/fix-android-build into feat/shaka
Reviewed-on: #7
Reviewed-by: Ivan Malison <ivanmalison@gmail.com>
2024-10-14 07:01:12 -06:00
47151c7119 Fix android build
Some checks failed
Build Android / Build Android Example App (pull_request) Has been cancelled
Build Android / Build Android Example App Without Ads (pull_request) Has been cancelled
Check Android / Kotlin-Lint (pull_request) Has been cancelled
2024-10-14 11:02:21 +02:00
a16275b003 ts-ignores 2024-10-13 22:48:51 -06:00
56c129aa4f Don't patch package anymore 2024-10-13 22:45:06 -06:00
68cbe3c4b1 Don't require rate to be defined 2024-10-13 20:45:25 -06:00
81e864c0e1 Update shaka when nativeRef changes 2024-10-13 19:17:01 -06:00
0e9ac4d125 Shaka loggin 2024-10-13 15:14:48 -06:00
9191a06600 Simple shaka 2024-10-13 15:04:44 -06:00
dc61c3efea Fix tsc 2024-10-13 14:18:49 -06:00
11f480f206 Start muted 2024-10-13 14:15:28 -06:00
9619e7517b Try again 2024-10-13 02:06:12 -06:00
3ddc6e931a More hacks 2024-10-13 01:09:57 -06:00
6b5831dc1c Hacks 2024-10-13 01:07:48 -06:00
3fc002f3fd Fix ts issues 2024-10-13 00:44:54 -06:00
edb5c6bcfa Merge remote-tracking branch 'railbird/master' into feat/shaka 2024-10-12 23:52:26 -06:00
5bc975b2c9 Shaka? 2024-10-12 23:48:55 -06:00
d79b5c9a83 Merge remote-tracking branch 'origin/master' into feat/web 2024-10-12 23:40:00 -06:00
f72b44d4df Merge pull request 'Implement onSeekComplete for Android' (#5) from kat/temp-4 into master
Some checks failed
Build Android / Build Android Example App (push) Has been cancelled
Build Android / Build Android Example App Without Ads (push) Has been cancelled
Check Android / Kotlin-Lint (push) Has been cancelled
Reviewed-on: #5
2024-08-26 17:23:32 -06:00
d2ab22b99f wip
Some checks failed
Build Android / Build Android Example App (pull_request) Has been cancelled
Build Android / Build Android Example App Without Ads (pull_request) Has been cancelled
Check Android / Kotlin-Lint (pull_request) Has been cancelled
2024-08-26 17:22:38 -06:00
2dcde42fd6 Add logs 2024-08-26 17:22:38 -06:00
c7a45d421b Only complete seek if seek was in progress 2024-08-26 17:22:38 -06:00
f0db0a6868 kat wip 2024-08-26 17:22:38 -06:00
01b3322e03 Log in seek 2024-08-26 17:22:38 -06:00
13beae1401 Merge pull request 'Implement ios onSeekComplete' (#3) from kat/seek-complete-ios into master
Some checks failed
Build iOS / Build iOS Example App (push) Has been cancelled
Build iOS / Build iOS Example App With Ads (push) Has been cancelled
Build iOS / Build iOS Example App With Caching (push) Has been cancelled
Check CLang / CLang-Format (push) Has been cancelled
Check iOS / Swift-Lint (push) Has been cancelled
Check iOS / Swift-Format (push) Has been cancelled
Reviewed-on: #3
2024-08-20 22:37:10 -06:00
f3deabd75e Implement ios onSeekComplete
Some checks failed
Build iOS / Build iOS Example App (pull_request) Has been cancelled
Build iOS / Build iOS Example App With Ads (pull_request) Has been cancelled
Build iOS / Build iOS Example App With Caching (pull_request) Has been cancelled
Check CLang / CLang-Format (pull_request) Has been cancelled
Check iOS / Swift-Lint (pull_request) Has been cancelled
Check iOS / Swift-Format (pull_request) Has been cancelled
2024-08-20 22:24:00 -06:00
d69729dc04 expose-on-seek-complete (#1)
Some checks failed
Build iOS / Build iOS Example App (push) Has been cancelled
Build iOS / Build iOS Example App With Ads (push) Has been cancelled
Build iOS / Build iOS Example App With Caching (push) Has been cancelled
Check CLang / CLang-Format (push) Has been cancelled
Check iOS / Swift-Lint (push) Has been cancelled
Check iOS / Swift-Format (push) Has been cancelled
Check JS / Check TS (tsc) (push) Has been cancelled
Check JS / Lint JS (eslint, prettier) (push) Has been cancelled
Reviewed-on: #1
2024-08-06 00:11:17 -06:00
Zoe Roux
6768c22139
Add nativeHtmlVideoRef doc 2024-07-16 12:31:32 +07:00
Zoe Roux
2b369df57d
Fix native import on web 2024-07-16 12:31:32 +07:00
Zoe Roux
8542c8f7d1
Add isSeeking on web 2024-07-16 12:31:32 +07:00
Zoe Roux
fc5b2d4563
Add web support for fullscreen 2024-07-16 11:33:50 +07:00
Zoe Roux
ffb4631854
Remove unused errorHandler ref 2024-07-16 11:33:50 +07:00
Zoe Roux
29cf7c97c3
Update doc for web 2024-07-16 11:33:50 +07:00
Zoe Roux
491ed77a32
Renamve nativeHtmlRef to nativeHtmlVideoRef 2024-07-16 11:33:50 +07:00
Zoe Roux
5b199b52b4
Move video style to const var 2024-07-16 11:33:50 +07:00
Zoe Roux
9d19157654
Add web command in basic example 2024-07-16 11:33:50 +07:00
Zoe Roux
3dabf5f16f
Fix and improve VideoNativeComponent (canPlay/isWidewine supportd) for web 2024-07-16 11:33:50 +07:00
Zoe Roux
e610a274d5
Prevent playback state change loop on web 2024-07-16 11:33:50 +07:00
Zoe Roux
27880f5212
Update the doc for web things 2024-07-16 11:33:50 +07:00
Zoe Roux
39dd30b762
Cleanup media session handling on the web 2024-07-16 11:33:50 +07:00
Zoe Roux
edf5d0c613
Test notifications on web 2024-07-16 11:33:50 +07:00
Zoe Roux
975fc2f303
Fix web bugs 2024-07-16 11:33:49 +07:00
Zoe Roux
aa85d71b87
Make the basic example app work on web 2024-07-16 11:33:18 +07:00
Zoe Roux
cce24cd829
Add media session support 2024-07-16 11:33:18 +07:00
Zoe Roux
cad63d465d
Add most properties 2024-07-16 11:33:18 +07:00
Zoe Roux
f5fa063bc0
Add most events 2024-07-16 11:33:18 +07:00
Zoe Roux
c6abcdeb2f
Create ref handling and basics stollen from Kyoo 2024-07-16 11:33:18 +07:00
Zoe Roux
a72ab331dc
Move video ref type to its own file 2024-07-16 11:33:15 +07:00
Zoe Roux
fa126de97f
Add VideoDecoderProperties for the web 2024-07-16 11:24:52 +07:00
Zoe Roux
ca2452edb6
Add shell.nix for nix users 2024-07-16 11:20:12 +07:00
12 changed files with 9911 additions and 25 deletions

View File

@ -22,6 +22,7 @@ enum class EventTypes(val eventName: String) {
EVENT_BANDWIDTH("onVideoBandwidthUpdate"),
EVENT_CONTROLS_VISIBILITY_CHANGE("onControlsVisibilityChange"),
EVENT_SEEK("onVideoSeek"),
EVENT_SEEK_COMPLETE("onVideoSeekComplete"),
EVENT_END("onVideoEnd"),
EVENT_FULLSCREEN_WILL_PRESENT("onVideoFullscreenPlayerWillPresent"),
EVENT_FULLSCREEN_DID_PRESENT("onVideoFullscreenPlayerDidPresent"),
@ -71,6 +72,7 @@ class VideoEventEmitter {
lateinit var onVideoBandwidthUpdate: (bitRateEstimate: Long, height: Int, width: Int, trackId: String?) -> Unit
lateinit var onVideoPlaybackStateChanged: (isPlaying: Boolean, isSeeking: Boolean) -> Unit
lateinit var onVideoSeek: (currentPosition: Long, seekTime: Long) -> Unit
lateinit var onVideoSeekComplete: (currentPosition: Long) -> Unit
lateinit var onVideoEnd: () -> Unit
lateinit var onVideoFullscreenPlayerWillPresent: () -> Unit
lateinit var onVideoFullscreenPlayerDidPresent: () -> Unit
@ -174,6 +176,11 @@ class VideoEventEmitter {
putDouble("seekTime", seekTime / 1000.0)
}
}
onVideoSeekComplete = { currentPosition ->
event.dispatch(EventTypes.EVENT_SEEK_COMPLETE) {
putDouble("currentTime", currentPosition / 1000.0)
}
}
onVideoEnd = {
event.dispatch(EventTypes.EVENT_END)
}

View File

@ -23,6 +23,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout;
@ -221,6 +222,7 @@ public class ReactExoplayerView extends FrameLayout implements
*/
private boolean isSeeking = false;
private long seekPosition = -1;
private boolean isSeekInProgress = false;
// Props from React
private Source source = new Source();
@ -300,6 +302,16 @@ public class ReactExoplayerView extends FrameLayout implements
}
};
private void handleSeekCompletion() {
if (player != null && player.getPlaybackState() == Player.STATE_READY && isSeekInProgress) {
Log.d("ReactExoplayerView", "handleSeekCompletion: currentPosition=" + player.getCurrentPosition());
eventEmitter.onVideoSeekComplete.invoke(player.getCurrentPosition());
isSeeking = false;
seekPosition = -1;
isSeekInProgress = false;
}
}
public double getPositionInFirstPeriodMsForCurrentWindow(long currentPosition) {
Timeline.Window window = new Timeline.Window();
if(!player.getCurrentTimeline().isEmpty()) {
@ -518,12 +530,21 @@ public class ReactExoplayerView extends FrameLayout implements
builder.setSingleChoiceItems(speedOptions, selectedSpeedIndex, (dialog, which) -> {
selectedSpeedIndex = which;
float speed = switch (which) {
case 0 -> 0.5f;
case 2 -> 1.5f;
case 3 -> 2.0f;
default -> 1.0f;
};
float speed;
switch (which) {
case 0:
speed = 0.5f;
break;
case 1:
speed = 1.0f;
break;
case 2:
speed = 1.5f;
break;
default:
speed = 1.0f;
break;
}
setRateModifier(speed);
});
builder.show();
@ -842,7 +863,8 @@ public class ReactExoplayerView extends FrameLayout implements
.setBandwidthMeter(bandwidthMeter)
.setLoadControl(loadControl)
.setMediaSourceFactory(mediaSourceFactory)
.build();
.build();
player.addListener(self);
ReactNativeVideoManager.Companion.getInstance().onInstanceCreated(instanceId, player);
refreshDebugState();
player.addListener(self);
@ -1451,6 +1473,7 @@ public class ReactExoplayerView extends FrameLayout implements
if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) {
int playbackState = player.getPlaybackState();
boolean playWhenReady = player.getPlayWhenReady();
Log.d("ReactExoplayerView", "onEvents: playbackState=" + playbackState + ", playWhenReady=" + playWhenReady);
String text = "onStateChanged: playWhenReady=" + playWhenReady + ", playbackState=";
eventEmitter.onPlaybackRateChange.invoke(playWhenReady && playbackState == ExoPlayer.STATE_READY ? 1.0f : 0.0f);
switch (playbackState) {
@ -1484,6 +1507,10 @@ public class ReactExoplayerView extends FrameLayout implements
playerControlView.show();
}
setKeepScreenOn(preventsDisplaySleepDuringVideoPlayback);
Log.d("ReactExoplayerView", "Player STATE_READY: currentPosition=" + player.getCurrentPosition());
if (isSeekInProgress) {
handleSeekCompletion();
}
break;
case Player.STATE_ENDED:
text += "ended";
@ -1748,6 +1775,7 @@ public class ReactExoplayerView extends FrameLayout implements
@Override
public void onPositionDiscontinuity(@NonNull Player.PositionInfo oldPosition, @NonNull Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) {
Log.d("ReactExoplayerView", "onPositionDiscontinuity: reason=" + reason + ", oldPosition=" + oldPosition.positionMs + ", newPosition=" + newPosition.positionMs);
if (reason == Player.DISCONTINUITY_REASON_SEEK) {
isSeeking = true;
seekPosition = newPosition.positionMs;
@ -2259,6 +2287,10 @@ public class ReactExoplayerView extends FrameLayout implements
public void seekTo(long positionMs) {
if (player != null) {
Log.d("ReactExoplayerView", "seekTo: positionMs=" + positionMs);
isSeekInProgress = true;
isSeeking = true;
seekPosition = positionMs;
player.seekTo(positionMs);
}
}

View File

@ -0,0 +1,52 @@
{
"name": "VideoPlayer",
"version": "1.0.0",
"private": true,
"scripts": {
"web": "expo start --web",
"android": "expo run:android",
"ios": "expo run:ios",
"windows": "react-native run-windows",
"start": "expo start",
"test": "jest",
"lint": "eslint .",
"pod-install": "cd ios && pod install && cd ..",
"pod-install:newarch": "cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install && cd .."
},
"dependencies": {
"@expo/metro-runtime": "~3.2.1",
"@react-native-picker/picker": "2.7.5",
"expo": "^51.0.32",
"expo-asset": "~10.0.10",
"expo-image": "^1.12.15",
"expo-navigation-bar": "~3.0.7",
"react": "18.2.0",
"react-native": "0.74.5",
"react-dom": "18.2.0",
"react-native-web": "~0.19.10",
"react-native-windows": "0.74.19"
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.22.10",
"@babel/runtime": "^7.22.10",
"@react-native/babel-preset": "0.74.85",
"@react-native/eslint-config": "0.74.85",
"@react-native/metro-config": "0.74.85",
"@react-native/typescript-config": "0.74.85",
"@types/react": "~18.2.79",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"babel-plugin-module-resolver": "5.0.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "^2.8.8",
"typescript": "~5.3.3"
},
"resolutions": {
"@types/react": "^18.0.24"
},
"engines": {
"node": ">=18"
}
}

View File

@ -0,0 +1,4 @@
import {registerRootComponent} from 'expo';
import VideoPlayer from './VideoPlayer';
registerRootComponent(VideoPlayer);

9711
examples/basic/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -113,6 +113,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc var onVideoProgress: RCTDirectEventBlock?
@objc var onVideoBandwidthUpdate: RCTDirectEventBlock?
@objc var onVideoSeek: RCTDirectEventBlock?
@objc var onVideoSeekComplete: RCTDirectEventBlock?
@objc var onVideoEnd: RCTDirectEventBlock?
@objc var onTimedMetadata: RCTDirectEventBlock?
@objc var onVideoAudioBecomingNoisy: RCTDirectEventBlock?
@ -782,34 +783,50 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
_paused = paused
}
@objc
func setSeek(_ time: NSNumber, _ tolerance: NSNumber) {
let item: AVPlayerItem? = _player?.currentItem
_pendingSeek = true
guard item != nil, let player = _player, let item, item.status == AVPlayerItem.Status.readyToPlay else {
_pendingSeek = true
_pendingSeekTime = time.floatValue
return
}
RCTPlayerOperations.seek(
player: player,
playerItem: item,
paused: _paused,
seekTime: time.floatValue,
seekTolerance: tolerance.floatValue
) { [weak self] (_: Bool) in
guard let self else { return }
let wasPaused = _paused
let seekTime = CMTimeMakeWithSeconds(Float64(time.floatValue), preferredTimescale: Int32(NSEC_PER_SEC))
let toleranceTime = CMTimeMakeWithSeconds(Float64(tolerance.floatValue), preferredTimescale: Int32(NSEC_PER_SEC))
let currentTimeBeforeSeek = CMTimeGetSeconds(item.currentTime())
// Call onVideoSeek before starting the seek operation
let currentTime = NSNumber(value: Float(currentTimeBeforeSeek))
self.onVideoSeek?(["currentTime": currentTime,
"seekTime": time,
"target": self.reactTag])
_pendingSeek = true
let seekCompletionHandler: (Bool) -> Void = { [weak self] finished in
guard let self = self else { return }
self._pendingSeek = false
guard finished else {
return
}
self._playerObserver.addTimeObserverIfNotSet()
self.setPaused(self._paused)
self.onVideoSeek?(["currentTime": NSNumber(value: Float(CMTimeGetSeconds(item.currentTime()))),
"seekTime": time,
"target": self.reactTag as Any])
let newCurrentTime = NSNumber(value: Float(CMTimeGetSeconds(item.currentTime())))
self.onVideoSeekComplete?(["currentTime": newCurrentTime,
"seekTime": time,
"target": self.reactTag as Any])
}
_pendingSeek = false
player.seek(to: seekTime, toleranceBefore: toleranceTime, toleranceAfter: toleranceTime, completionHandler: seekCompletionHandler)
}
@objc
@ -1688,3 +1705,4 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc
func setOnClick(_: Any) {}
}

View File

@ -45,6 +45,7 @@ RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoBandwidthUpdate, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoSeekComplete, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoAudioBecomingNoisy, RCTDirectEventBlock);

View File

@ -32,9 +32,12 @@
"react-native": "0.73.2",
"react-native-windows": "^0.61.0-0",
"release-it": "^16.2.1",
"typescript": "5.1.6"
"typescript": "5.1.6",
"patch-package": "^8.0.0"
},
"dependencies": {
"shaka-player": "^4.11.7"
},
"dependencies": {},
"peerDependencies": {
"react": "*",
"react-native": "*"

View File

@ -0,0 +1,39 @@
diff --git a/node_modules/shaka-player/dist/shaka-player.compiled.d.ts b/node_modules/shaka-player/dist/shaka-player.compiled.d.ts
index 19c0930..cc0a3fd 100644
--- a/node_modules/shaka-player/dist/shaka-player.compiled.d.ts
+++ b/node_modules/shaka-player/dist/shaka-player.compiled.d.ts
@@ -5117,3 +5117,5 @@ declare namespace shaka.extern {
declare namespace shaka.extern {
type TransmuxerPlugin = ( ) => shaka.extern.Transmuxer ;
}
+
+export default shaka;
diff --git a/node_modules/shaka-player/dist/shaka-player.ui.d.ts b/node_modules/shaka-player/dist/shaka-player.ui.d.ts
index 1618ca0..a6076c6 100644
--- a/node_modules/shaka-player/dist/shaka-player.ui.d.ts
+++ b/node_modules/shaka-player/dist/shaka-player.ui.d.ts
@@ -5830,3 +5830,5 @@ declare namespace shaka.extern {
declare namespace shaka.extern {
type UIVolumeBarColors = { base : string , level : string } ;
}
+
+export default shaka;
diff --git a/node_modules/shaka-player/index.d.ts b/node_modules/shaka-player/index.d.ts
new file mode 100644
index 0000000..3ebfd96
--- /dev/null
+++ b/node_modules/shaka-player/index.d.ts
@@ -0,0 +1,2 @@
+/// <reference path="./dist/shaka-player.compiled.d.ts" />
+/// <reference path="./dist/shaka-player.ui.d.ts" />
\ No newline at end of file
diff --git a/node_modules/shaka-player/ui.d.ts b/node_modules/shaka-player/ui.d.ts
new file mode 100644
index 0000000..84a3be0
--- /dev/null
+++ b/node_modules/shaka-player/ui.d.ts
@@ -0,0 +1,3 @@
+import shaka from 'shaka-player/dist/shaka-player.ui'
+export * from 'shaka-player/dist/shaka-player.ui'
+export default shaka;
\ No newline at end of file

View File

@ -32,6 +32,7 @@ import type {
OnPlaybackStateChangedData,
OnProgressData,
OnSeekData,
OnSeekCompleteData,
OnTextTrackDataChangedData,
OnTimedMetadataData,
OnVideoAspectRatioData,
@ -45,7 +46,7 @@ import {
resolveAssetSourceForVideo,
} from './utils';
import NativeVideoManager from './specs/NativeVideoManager';
import {ViewType, CmcdMode, VideoRef} from './types';
import {type VideoSaveData, ViewType, CmcdMode, VideoRef} from './types';
import type {
OnLoadData,
OnTextTracksData,
@ -81,6 +82,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onError,
onProgress,
onSeek,
onSeekComplete,
onEnd,
onBuffer,
onBandwidthUpdate,
@ -469,6 +471,13 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
[onSeek],
);
const onVideoSeekComplete = useCallback(
(e: NativeSyntheticEvent<OnSeekCompleteData>) => {
onSeekComplete?.(e.nativeEvent);
},
[onSeekComplete]
);
const onVideoPlaybackStateChanged = useCallback(
(e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => {
onPlaybackStateChanged?.(e.nativeEvent);
@ -810,6 +819,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onVideoError={onError ? onVideoError : undefined}
onVideoProgress={onProgress ? onVideoProgress : undefined}
onVideoSeek={onSeek ? onVideoSeek : undefined}
onVideoSeekComplete={onSeekComplete ? onVideoSeekComplete : undefined}
onVideoEnd={onEnd}
onVideoBuffer={onBuffer ? onVideoBuffer : undefined}
onVideoPlaybackStateChanged={

View File

@ -205,6 +205,12 @@ export type OnSeekData = Readonly<{
seekTime: Float;
}>;
export type OnSeekCompleteData = Readonly<{
currentTime: number;
seekTime: number;
target: number;
}>;
export type OnPlaybackStateChangedData = Readonly<{
isPlaying: boolean;
isSeeking: boolean;
@ -378,6 +384,7 @@ export interface VideoNativeProps extends ViewProps {
onVideoProgress?: DirectEventHandler<OnProgressData>;
onVideoBandwidthUpdate?: DirectEventHandler<OnBandwidthUpdateData>;
onVideoSeek?: DirectEventHandler<OnSeekData>;
onVideoSeekComplete?: DirectEventHandler<OnSeekCompleteData>;
onVideoEnd?: DirectEventHandler<{}>; // all
onVideoAudioBecomingNoisy?: DirectEventHandler<{}>;
onVideoFullscreenPlayerWillPresent?: DirectEventHandler<{}>; // ios, android

View File

@ -12,6 +12,7 @@ import type {
OnPlaybackStateChangedData,
OnProgressData,
OnSeekData,
OnSeekCompleteData,
OnTextTrackDataChangedData,
OnTimedMetadataData,
OnVideoAspectRatioData,
@ -260,6 +261,7 @@ export interface ReactVideoEvents {
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS
onRestoreUserInterfaceForPictureInPictureStop?: () => void; //iOS
onSeek?: (e: OnSeekData) => void; //Android, iOS, Windows UWP
onSeekComplete?: (e: OnSeekCompleteData) => void; // iOS
onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void; // Android, iOS
onTimedMetadata?: (e: OnTimedMetadataData) => void; //Android, iOS
onAudioTracks?: (e: OnAudioTracksData) => void; // Android