@cinecrew/cinecrew-player 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CineCrewPlayer.podspec +22 -0
- package/LICENSE +21 -0
- package/NOTICE +6 -0
- package/README.md +574 -0
- package/android/build.gradle +48 -0
- package/android/proguard-rules.pro +29 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/yuanzhou/vlc/ReactVlcPlayerPackage.java +28 -0
- package/android/src/main/java/com/yuanzhou/vlc/vlcplayer/ReactVlcPlayerView.java +988 -0
- package/android/src/main/java/com/yuanzhou/vlc/vlcplayer/ReactVlcPlayerViewManager.java +208 -0
- package/android/src/main/java/com/yuanzhou/vlc/vlcplayer/VideoEventEmitter.java +136 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/app.plugin.cjs +1 -0
- package/assets/cinecrew-player-logo.svg +44 -0
- package/package.json +132 -0
- package/packages/react-native-vlc-media-player/LICENSE +21 -0
- package/packages/react-native-vlc-media-player/VLCPlayer.js +207 -0
- package/packages/react-native-vlc-media-player/expo/android/withGradleTasks.cjs +49 -0
- package/packages/react-native-vlc-media-player/expo/ios/withMobileVlcKit.cjs +28 -0
- package/packages/react-native-vlc-media-player/expo/withVlcMediaPlayer.cjs +10 -0
- package/packages/react-native-vlc-media-player/index.d.ts +354 -0
- package/packages/react-native-vlc-media-player/ios/RCTVLCPlayer/RCTVLCPlayer.h +36 -0
- package/packages/react-native-vlc-media-player/ios/RCTVLCPlayer/RCTVLCPlayer.m +635 -0
- package/packages/react-native-vlc-media-player/ios/RCTVLCPlayer/RCTVLCPlayerManager.h +5 -0
- package/packages/react-native-vlc-media-player/ios/RCTVLCPlayer/RCTVLCPlayerManager.m +100 -0
- package/src/native/InlineLivePlayer.js +321 -0
- package/src/native/MediaPlayerView.js +3093 -0
- package/src/native/customization.js +44 -0
- package/src/native/index.js +107 -0
- package/src/native/media/ElectronVideoPlayer.js +288 -0
- package/src/native/media/EmojiPickerModal.js +30 -0
- package/src/native/media/LiveChatDrawer.js +1177 -0
- package/src/native/media/LiveRecordingOverlay.js +319 -0
- package/src/native/media/WebVideoPlayer.js +320 -0
- package/src/native/media/YouTubeVideoPlayer.native.js +120 -0
- package/src/native/media/YouTubeVideoPlayer.web.js +169 -0
- package/src/native/media/player/AudioOnlyView.js +337 -0
- package/src/native/media/player/CenterControls.js +94 -0
- package/src/native/media/player/ExoVideoFallback.js +329 -0
- package/src/native/media/player/PipOverlay.js +1 -0
- package/src/native/media/player/PlayerBottomBar.js +295 -0
- package/src/native/media/player/PlayerTopBar.js +255 -0
- package/src/native/media/player/VLCBoundary.js +41 -0
- package/src/native/media/player/VerticalIndicator.js +184 -0
- package/src/native/media/player/index.js +9 -0
- package/src/native/media/player/playerConstants.js +159 -0
- package/src/native/media/web/useWebAc3AudioPlayback.native.js +6 -0
- package/src/native/media/web/useWebAc3AudioPlayback.web.js +219 -0
- package/src/native/media/web/useWebHlsPlayback.native.js +3 -0
- package/src/native/media/web/useWebHlsPlayback.web.js +66 -0
- package/src/native/media/web/useWebMediaSession.js +90 -0
- package/src/native/media/web/useWebMpegTsPlayback.native.js +3 -0
- package/src/native/media/web/useWebMpegTsPlayback.web.js +356 -0
- package/src/native/media/web/useWebVideoAspectRatio.js +52 -0
- package/src/native/media/web/webPlaybackErrors.js +4 -0
- package/src/utils/layoutUtils.js +12 -0
- package/src/utils/mediaUtils.js +7 -0
- package/src/utils/recording.js +8 -0
- package/src/utils/runtimePlatform.js +19 -0
- package/src/utils/sourceUtils.js +99 -0
- package/src/utils/youtubeHtml.js +34 -0
- package/src/web/index.js +1129 -0
- package/src/web/styles.css +378 -0
- package/types/index.d.ts +268 -0
- package/vendor/mpegts.js/LICENSE +202 -0
- package/vendor/mpegts.js/mpegts.js +3 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
|
|
2
|
+
import ReactNative from 'react-native';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
|
5
|
+
|
|
6
|
+
const { StyleSheet, requireNativeComponent, View, UIManager } = ReactNative;
|
|
7
|
+
|
|
8
|
+
const VLCPlayer = forwardRef(function VLCPlayer(props, forwardedRef) {
|
|
9
|
+
const {
|
|
10
|
+
autoplay = true,
|
|
11
|
+
source: sourceProp,
|
|
12
|
+
repeat,
|
|
13
|
+
onBuffering,
|
|
14
|
+
onError,
|
|
15
|
+
onOpen,
|
|
16
|
+
onLoadStart,
|
|
17
|
+
onProgress,
|
|
18
|
+
onEnd,
|
|
19
|
+
onStopped,
|
|
20
|
+
onPaused,
|
|
21
|
+
onPlaying,
|
|
22
|
+
onLoad,
|
|
23
|
+
onRecordingCreated,
|
|
24
|
+
onSnapshot,
|
|
25
|
+
...otherProps
|
|
26
|
+
} = props;
|
|
27
|
+
const rootRef = useRef(null);
|
|
28
|
+
const lastRecordingRef = useRef(null);
|
|
29
|
+
|
|
30
|
+
useImperativeHandle(forwardedRef, () => {
|
|
31
|
+
const dispatchCommand = (command, args) => {
|
|
32
|
+
const viewTag = ReactNative.findNodeHandle(rootRef.current);
|
|
33
|
+
if (viewTag == null) return;
|
|
34
|
+
const manager = UIManager.getViewManagerConfig('RCTVLCPlayer');
|
|
35
|
+
const commandId = manager?.Commands?.[command];
|
|
36
|
+
if (commandId == null) return;
|
|
37
|
+
UIManager.dispatchViewManagerCommand(viewTag, commandId, args);
|
|
38
|
+
};
|
|
39
|
+
const setNativeProps = (nativeProps) => rootRef.current?.setNativeProps?.(nativeProps);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
setNativeProps,
|
|
43
|
+
startRecording: (path) => dispatchCommand('startRecording', [path]),
|
|
44
|
+
stopRecording: () => dispatchCommand('stopRecording', []),
|
|
45
|
+
stopPlayer: () => dispatchCommand('stopPlayer', []),
|
|
46
|
+
snapshot: (path) => dispatchCommand('snapshot', [path]),
|
|
47
|
+
seek: (position) => setNativeProps({ seek: position }),
|
|
48
|
+
resume: (shouldResume) => setNativeProps({ resume: shouldResume }),
|
|
49
|
+
autoAspectRatio: (isAuto) => setNativeProps({ autoAspectRatio: isAuto }),
|
|
50
|
+
changeVideoAspectRatio: (ratio) => setNativeProps({ videoAspectRatio: ratio }),
|
|
51
|
+
_onStopped: () => {
|
|
52
|
+
setNativeProps({ paused: true });
|
|
53
|
+
onStopped?.();
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}, [onStopped]);
|
|
57
|
+
|
|
58
|
+
const handleNativeEvent = useCallback(
|
|
59
|
+
(callback) => (event) => callback?.(event.nativeEvent),
|
|
60
|
+
[],
|
|
61
|
+
);
|
|
62
|
+
const handleStopped = useCallback(
|
|
63
|
+
(event) => {
|
|
64
|
+
rootRef.current?.setNativeProps?.({ paused: true });
|
|
65
|
+
onStopped?.(event.nativeEvent);
|
|
66
|
+
},
|
|
67
|
+
[onStopped],
|
|
68
|
+
);
|
|
69
|
+
const handleRecordingState = useCallback(
|
|
70
|
+
(event) => {
|
|
71
|
+
const { isRecording, recordPath } = event.nativeEvent;
|
|
72
|
+
if (lastRecordingRef.current === recordPath) return;
|
|
73
|
+
if (!isRecording && recordPath) {
|
|
74
|
+
lastRecordingRef.current = recordPath;
|
|
75
|
+
onRecordingCreated?.(recordPath);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
[onRecordingCreated],
|
|
79
|
+
);
|
|
80
|
+
const handleSnapshot = useCallback(
|
|
81
|
+
(event) => {
|
|
82
|
+
if (event.nativeEvent.success) onSnapshot?.(event.nativeEvent);
|
|
83
|
+
},
|
|
84
|
+
[onSnapshot],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const resolvedSource = resolveAssetSource(sourceProp) || {};
|
|
88
|
+
const source = { ...resolvedSource };
|
|
89
|
+
if (Array.isArray(resolvedSource.initOptions)) {
|
|
90
|
+
source.initOptions = [...resolvedSource.initOptions];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let uri = source.uri || '';
|
|
94
|
+
if (uri.startsWith('/')) uri = `file://${uri}`;
|
|
95
|
+
|
|
96
|
+
let isNetwork = /^https?:/i.test(uri);
|
|
97
|
+
const isAsset = /^(assets-library|file|content|ms-appx|ms-appdata):/i.test(uri);
|
|
98
|
+
if (!isAsset) isNetwork = true;
|
|
99
|
+
if (uri.startsWith('/')) isNetwork = false;
|
|
100
|
+
source.isNetwork = isNetwork;
|
|
101
|
+
source.autoplay = autoplay;
|
|
102
|
+
source.initOptions = source.initOptions || [];
|
|
103
|
+
|
|
104
|
+
if (repeat) {
|
|
105
|
+
const hasRepeatOption = source.initOptions.some(
|
|
106
|
+
(item) => item.startsWith('--repeat') || item.startsWith('--input-repeat'),
|
|
107
|
+
);
|
|
108
|
+
if (!hasRepeatOption) source.initOptions.push('--repeat');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const nativeProps = {
|
|
112
|
+
...otherProps,
|
|
113
|
+
autoplay,
|
|
114
|
+
repeat,
|
|
115
|
+
style: [styles.base, otherProps.style],
|
|
116
|
+
source,
|
|
117
|
+
src: {
|
|
118
|
+
uri,
|
|
119
|
+
isNetwork,
|
|
120
|
+
isAsset,
|
|
121
|
+
type: source.type || '',
|
|
122
|
+
mainVer: source.mainVer || 0,
|
|
123
|
+
patchVer: source.patchVer || 0,
|
|
124
|
+
},
|
|
125
|
+
onVideoLoadStart: handleNativeEvent(onLoadStart),
|
|
126
|
+
onVideoOpen: handleNativeEvent(onOpen),
|
|
127
|
+
onVideoError: handleNativeEvent(onError),
|
|
128
|
+
onVideoProgress: handleNativeEvent(onProgress),
|
|
129
|
+
onVideoEnded: handleNativeEvent(onEnd),
|
|
130
|
+
onVideoEnd: handleNativeEvent(onEnd),
|
|
131
|
+
onVideoPlaying: handleNativeEvent(onPlaying),
|
|
132
|
+
onVideoPaused: handleNativeEvent(onPaused),
|
|
133
|
+
onVideoStopped: handleStopped,
|
|
134
|
+
onVideoBuffering: handleNativeEvent(onBuffering),
|
|
135
|
+
onVideoLoad: handleNativeEvent(onLoad),
|
|
136
|
+
onRecordingState: handleRecordingState,
|
|
137
|
+
onSnapshot: handleSnapshot,
|
|
138
|
+
progressUpdateInterval: onProgress ? 250 : 0,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return <NativeVLCPlayer ref={rootRef} {...nativeProps} />;
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
VLCPlayer.displayName = 'VLCPlayer';
|
|
145
|
+
VLCPlayer.propTypes = {
|
|
146
|
+
rate: PropTypes.number,
|
|
147
|
+
seek: PropTypes.number,
|
|
148
|
+
resume: PropTypes.bool,
|
|
149
|
+
paused: PropTypes.bool,
|
|
150
|
+
autoAspectRatio: PropTypes.bool,
|
|
151
|
+
videoAspectRatio: PropTypes.string,
|
|
152
|
+
volume: PropTypes.number,
|
|
153
|
+
disableFocus: PropTypes.bool,
|
|
154
|
+
src: PropTypes.string,
|
|
155
|
+
playInBackground: PropTypes.bool,
|
|
156
|
+
playWhenInactive: PropTypes.bool,
|
|
157
|
+
resizeMode: PropTypes.string,
|
|
158
|
+
poster: PropTypes.string,
|
|
159
|
+
muted: PropTypes.bool,
|
|
160
|
+
audioTrack: PropTypes.number,
|
|
161
|
+
textTrack: PropTypes.number,
|
|
162
|
+
acceptInvalidCertificates: PropTypes.bool,
|
|
163
|
+
onVideoLoadStart: PropTypes.func,
|
|
164
|
+
onVideoError: PropTypes.func,
|
|
165
|
+
onVideoProgress: PropTypes.func,
|
|
166
|
+
onVideoEnded: PropTypes.func,
|
|
167
|
+
onVideoEnd: PropTypes.func,
|
|
168
|
+
onVideoPlaying: PropTypes.func,
|
|
169
|
+
onVideoPaused: PropTypes.func,
|
|
170
|
+
onVideoStopped: PropTypes.func,
|
|
171
|
+
onVideoBuffering: PropTypes.func,
|
|
172
|
+
onVideoOpen: PropTypes.func,
|
|
173
|
+
onVideoLoad: PropTypes.func,
|
|
174
|
+
onRecordingState: PropTypes.func,
|
|
175
|
+
onSnapshot: PropTypes.func,
|
|
176
|
+
autoplay: PropTypes.bool,
|
|
177
|
+
source: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.string]),
|
|
178
|
+
repeat: PropTypes.bool,
|
|
179
|
+
onBuffering: PropTypes.func,
|
|
180
|
+
onError: PropTypes.func,
|
|
181
|
+
onOpen: PropTypes.func,
|
|
182
|
+
onLoadStart: PropTypes.func,
|
|
183
|
+
onProgress: PropTypes.func,
|
|
184
|
+
onEnd: PropTypes.func,
|
|
185
|
+
onEnded: PropTypes.func,
|
|
186
|
+
onStopped: PropTypes.func,
|
|
187
|
+
onPaused: PropTypes.func,
|
|
188
|
+
onPlaying: PropTypes.func,
|
|
189
|
+
onLoad: PropTypes.func,
|
|
190
|
+
onRecordingCreated: PropTypes.func,
|
|
191
|
+
scaleX: PropTypes.number,
|
|
192
|
+
scaleY: PropTypes.number,
|
|
193
|
+
translateX: PropTypes.number,
|
|
194
|
+
translateY: PropTypes.number,
|
|
195
|
+
rotation: PropTypes.number,
|
|
196
|
+
...View.propTypes,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const NativeVLCPlayer = requireNativeComponent('RCTVLCPlayer', VLCPlayer);
|
|
200
|
+
|
|
201
|
+
const styles = StyleSheet.create({
|
|
202
|
+
base: {
|
|
203
|
+
overflow: 'hidden',
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
export default VLCPlayer;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const { withAppBuildGradle } = require('@expo/config-plugins');
|
|
2
|
+
const generateCode = require('@expo/config-plugins/build/utils/generateCode');
|
|
3
|
+
|
|
4
|
+
const resolveAppGradleString = (options) => {
|
|
5
|
+
const rnJetifierName = options?.android?.legacyJetifier
|
|
6
|
+
? 'jetified-react-native'
|
|
7
|
+
: 'jetified-react-android';
|
|
8
|
+
|
|
9
|
+
return `tasks.whenTaskAdded((tas -> {
|
|
10
|
+
if (tas.name.contains("merge") && tas.name.contains("NativeLibs")) {
|
|
11
|
+
tasks.named(tas.name) {it
|
|
12
|
+
doFirst {
|
|
13
|
+
java.nio.file.Path notNeededDirectory = it.externalLibNativeLibs
|
|
14
|
+
.getFiles()
|
|
15
|
+
.stream()
|
|
16
|
+
.filter(file -> file.toString().contains("${rnJetifierName}"))
|
|
17
|
+
.findAny()
|
|
18
|
+
.orElse(null)
|
|
19
|
+
.toPath();
|
|
20
|
+
java.nio.file.Files.walk(notNeededDirectory).forEach(file -> {
|
|
21
|
+
if (file.toString().contains("libc++_shared.so")) {
|
|
22
|
+
java.nio.file.Files.delete(file);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}))`;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const withGradleTasks = (config, options) => {
|
|
32
|
+
if (!options?.android) return config;
|
|
33
|
+
|
|
34
|
+
return withAppBuildGradle(config, (modConfig) => {
|
|
35
|
+
const newCode = generateCode.mergeContents({
|
|
36
|
+
tag: 'withVlcMediaPlayer',
|
|
37
|
+
src: modConfig.modResults.contents,
|
|
38
|
+
newSrc: resolveAppGradleString(options),
|
|
39
|
+
anchor: /applyNativeModulesAppBuildGradle\(project\)/i,
|
|
40
|
+
offset: 2,
|
|
41
|
+
comment: '//',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
modConfig.modResults.contents = newCode.contents;
|
|
45
|
+
return modConfig;
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
module.exports = withGradleTasks;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const { withDangerousMod } = require('@expo/config-plugins');
|
|
2
|
+
const generateCode = require('@expo/config-plugins/build/utils/generateCode');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
|
|
6
|
+
const withMobileVlcKit = (config, options) => {
|
|
7
|
+
if (!options?.ios?.includeVLCKit) return config;
|
|
8
|
+
|
|
9
|
+
return withDangerousMod(config, [
|
|
10
|
+
'ios',
|
|
11
|
+
(modConfig) => {
|
|
12
|
+
const filePath = path.join(modConfig.modRequest.platformProjectRoot, 'Podfile');
|
|
13
|
+
const contents = fs.readFileSync(filePath, 'utf-8');
|
|
14
|
+
const newCode = generateCode.mergeContents({
|
|
15
|
+
tag: 'withVlcMediaPlayer',
|
|
16
|
+
src: contents,
|
|
17
|
+
newSrc: " pod 'MobileVLCKit', '3.3.10'",
|
|
18
|
+
anchor: /use_expo_modules!/i,
|
|
19
|
+
offset: 3,
|
|
20
|
+
comment: ' #',
|
|
21
|
+
});
|
|
22
|
+
fs.writeFileSync(filePath, newCode.contents);
|
|
23
|
+
return modConfig;
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
module.exports = withMobileVlcKit;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const withGradleTasks = require('./android/withGradleTasks.cjs');
|
|
2
|
+
const withMobileVlcKit = require('./ios/withMobileVlcKit.cjs');
|
|
3
|
+
|
|
4
|
+
const withVlcMediaPlayer = (config, options) => {
|
|
5
|
+
config = withGradleTasks(config, options);
|
|
6
|
+
config = withMobileVlcKit(config, options);
|
|
7
|
+
return config;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
module.exports = withVlcMediaPlayer;
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { Component } from "react";
|
|
2
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Video aspect ratio type
|
|
6
|
+
*/
|
|
7
|
+
export type PlayerAspectRatio = "16:9" | "1:1" | "4:3" | "3:2" | "21:9" | "9:16";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Video resize mode
|
|
11
|
+
*/
|
|
12
|
+
export type PlayerResizeMode = "fill" | "contain" | "cover" | "none" | "scale-down";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* VLC Player source configuration options
|
|
16
|
+
*/
|
|
17
|
+
export interface VLCPlayerSource {
|
|
18
|
+
/**
|
|
19
|
+
* Media source URI to render
|
|
20
|
+
*/
|
|
21
|
+
uri: string;
|
|
22
|
+
/**
|
|
23
|
+
* VLC Player initialization type
|
|
24
|
+
*
|
|
25
|
+
* - Default configuration: `1`
|
|
26
|
+
* - Custom configuration: `2`
|
|
27
|
+
*
|
|
28
|
+
* See `initOptions` for more information
|
|
29
|
+
*
|
|
30
|
+
* @default 1
|
|
31
|
+
*/
|
|
32
|
+
initType?: 1 | 2;
|
|
33
|
+
/**
|
|
34
|
+
* https://wiki.videolan.org/VLC_command-line_help/
|
|
35
|
+
*
|
|
36
|
+
* VLC Player initialization options
|
|
37
|
+
*
|
|
38
|
+
* `["--network-caching=50", "--rtsp-tcp"]`
|
|
39
|
+
*
|
|
40
|
+
* If `repeat` is set on props this will default to ["--repeat"] unless
|
|
41
|
+
* another `--repeat` or `--input-repeat` flag is passed.
|
|
42
|
+
*
|
|
43
|
+
* @default []
|
|
44
|
+
*/
|
|
45
|
+
initOptions?: string[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Represents a track type in playback
|
|
50
|
+
*/
|
|
51
|
+
export type Track = {
|
|
52
|
+
/**
|
|
53
|
+
* Track identification
|
|
54
|
+
*/
|
|
55
|
+
id: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Track name
|
|
59
|
+
*/
|
|
60
|
+
name: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Represents a full playback information
|
|
65
|
+
*/
|
|
66
|
+
export type VideoInfo = {
|
|
67
|
+
/**
|
|
68
|
+
* Total playback duration
|
|
69
|
+
*/
|
|
70
|
+
duration: number;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Playback target
|
|
74
|
+
*/
|
|
75
|
+
target: number;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Total playback video size
|
|
79
|
+
*/
|
|
80
|
+
videoSize: Record<"width" | "height", number>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* List of playback audio tracks
|
|
84
|
+
*/
|
|
85
|
+
audioTracks: Track[];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* List of playback text tracks
|
|
89
|
+
*/
|
|
90
|
+
textTracks: Track[];
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type OnPlayingEventProps = Pick<VideoInfo, "duration" | "target"> & {
|
|
94
|
+
seekable: boolean;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
type OnProgressEventProps = Pick<VideoInfo, "duration" | "target"> & {
|
|
98
|
+
/**
|
|
99
|
+
* Current playback time
|
|
100
|
+
*/
|
|
101
|
+
currentTime: number;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Current playback position
|
|
105
|
+
*/
|
|
106
|
+
position: number;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Remaining time to end playback
|
|
110
|
+
*/
|
|
111
|
+
remainingTime: number;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
type SimpleCallbackEventProps = Pick<VideoInfo, "target">;
|
|
115
|
+
|
|
116
|
+
export type VLCPlayerCallbackProps = {
|
|
117
|
+
/**
|
|
118
|
+
* Called when media starts playing returns
|
|
119
|
+
*
|
|
120
|
+
* @param event - Event properties
|
|
121
|
+
*/
|
|
122
|
+
onPlaying?: (event: OnPlayingEventProps) => void;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Callback containing position as a fraction, and duration, currentTime and remainingTime in seconds
|
|
126
|
+
*
|
|
127
|
+
* @param event - Event properties
|
|
128
|
+
*/
|
|
129
|
+
onProgress?: (event: OnProgressEventProps) => void;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Called when media is paused
|
|
133
|
+
*
|
|
134
|
+
* @param event - Event properties
|
|
135
|
+
*/
|
|
136
|
+
onPaused?: (event: SimpleCallbackEventProps) => void;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Called when media is stoped
|
|
140
|
+
*
|
|
141
|
+
* @param event - Event properties
|
|
142
|
+
*/
|
|
143
|
+
onStopped?: (event: SimpleCallbackEventProps) => void;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Called when media is buffering
|
|
147
|
+
*
|
|
148
|
+
* @param event - Event properties
|
|
149
|
+
*/
|
|
150
|
+
onBuffering?: (event: SimpleCallbackEventProps) => void;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Called when media playing ends
|
|
154
|
+
*
|
|
155
|
+
* @param event - Event properties
|
|
156
|
+
*/
|
|
157
|
+
onEnd?: (event: SimpleCallbackEventProps) => void;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Called when an error occurs whilst attempting to play media
|
|
161
|
+
*
|
|
162
|
+
* @param event - Event properties
|
|
163
|
+
*/
|
|
164
|
+
onError?: (event: SimpleCallbackEventProps) => void;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Called when video info is loaded, Callback containing `VideoInfo`
|
|
168
|
+
*
|
|
169
|
+
* @param event - Event properties
|
|
170
|
+
*/
|
|
171
|
+
onLoad?: (event: VideoInfo) => void;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Called when a new recording is created
|
|
175
|
+
*
|
|
176
|
+
* @param recordingPath - Full path to the recording file
|
|
177
|
+
*/
|
|
178
|
+
onRecordingCreated?: (recordingPath: string) => void;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Called when a new snapshot is created
|
|
182
|
+
*
|
|
183
|
+
* @param event - Event properties
|
|
184
|
+
*/
|
|
185
|
+
onSnapshot?: (event: {
|
|
186
|
+
success: boolean;
|
|
187
|
+
path?: string;
|
|
188
|
+
error?: string;
|
|
189
|
+
}) => void;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export type VLCPlayerProps = VLCPlayerCallbackProps & {
|
|
193
|
+
/**
|
|
194
|
+
* Object that contains the uri of a video or song to play eg
|
|
195
|
+
*/
|
|
196
|
+
source: VLCPlayerSource;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* local subtitle file path,if you want to hide subtitle,
|
|
200
|
+
* you can set this to an empty subtitle file,
|
|
201
|
+
* current we don't support a hide subtitle prop.
|
|
202
|
+
*/
|
|
203
|
+
subtitleUri?: string;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Set to `true` or `false` to pause or play the media
|
|
207
|
+
* @default false
|
|
208
|
+
*/
|
|
209
|
+
paused?: boolean;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Set to `true` or `false` to loop the media
|
|
213
|
+
* @default false
|
|
214
|
+
*/
|
|
215
|
+
repeat?: boolean;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Set the playback rate of the player
|
|
219
|
+
* @default 1
|
|
220
|
+
*/
|
|
221
|
+
rate?: number;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Set position to seek between 0 and 1
|
|
225
|
+
* (0 being the start, 1 being the end, use position from the progress object)
|
|
226
|
+
*/
|
|
227
|
+
seek?: number;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Set the volume of the player
|
|
231
|
+
*/
|
|
232
|
+
volume?: number;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Set to `true` or `false` to mute the player
|
|
236
|
+
* @default false
|
|
237
|
+
*/
|
|
238
|
+
muted?: boolean;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Set audioTrack id (number) (see onLoad callback VideoInfo.audioTracks)
|
|
242
|
+
*/
|
|
243
|
+
audioTrack?: number;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Set textTrack(subtitle) id (number) (see onLoad callback - VideoInfo.textTracks)
|
|
247
|
+
*/
|
|
248
|
+
textTrack?: number;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Set to `true` or `false` to allow playing in the background
|
|
252
|
+
* @default false
|
|
253
|
+
*/
|
|
254
|
+
playInBackground?: boolean;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Video aspect ratio
|
|
258
|
+
*/
|
|
259
|
+
videoAspectRatio?: PlayerAspectRatio;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Set to `true` or `false` to enable auto aspect ratio
|
|
263
|
+
* @default false
|
|
264
|
+
*/
|
|
265
|
+
autoAspectRatio?: boolean;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Set the behavior for the video size (fill, contain, cover, none, scale-down)
|
|
269
|
+
*/
|
|
270
|
+
resizeMode?: PlayerResizeMode;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* React native view stylesheet styles
|
|
274
|
+
*/
|
|
275
|
+
style?: StyleProp<ViewStyle>;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Enables autoplay
|
|
279
|
+
*
|
|
280
|
+
* @default true
|
|
281
|
+
*/
|
|
282
|
+
autoplay?: boolean;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Set to `true` to automatically accept invalid SSL/TLS certificates
|
|
286
|
+
* when connecting to HTTPS streams. This bypasses certificate validation
|
|
287
|
+
* which may pose security risks.
|
|
288
|
+
*
|
|
289
|
+
* @default false
|
|
290
|
+
*/
|
|
291
|
+
acceptInvalidCertificates?: boolean;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
declare class PlaybackMethods<T> extends Component<T> {
|
|
295
|
+
/**
|
|
296
|
+
* Start a new recording session at the given path
|
|
297
|
+
* @param path Directory to create new recording in
|
|
298
|
+
*/
|
|
299
|
+
startRecording(path: string);
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Stop current recording session
|
|
303
|
+
*/
|
|
304
|
+
stopRecording();
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Stop playing
|
|
308
|
+
*/
|
|
309
|
+
stopPlayer();
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Take a screenshot of the current video frame
|
|
313
|
+
*
|
|
314
|
+
* @param path The file path where to save the screenshot
|
|
315
|
+
*/
|
|
316
|
+
snapshot(path: string);
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Seek to the given position
|
|
320
|
+
*
|
|
321
|
+
* @param pos Position to seek to (as a percentage of the full duration)
|
|
322
|
+
*/
|
|
323
|
+
seek(pos: number);
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Resume playback
|
|
327
|
+
*/
|
|
328
|
+
resume();
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Change auto aspect ratio setting
|
|
332
|
+
*
|
|
333
|
+
* @param useAuto Whether or not to use auto aspect ratio
|
|
334
|
+
*/
|
|
335
|
+
autoAspectRatio(useAuto: boolean);
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Update video aspect ratio e.g. `"16:9"`
|
|
339
|
+
*
|
|
340
|
+
* @param ratio Aspect ratio to use
|
|
341
|
+
*/
|
|
342
|
+
changeVideoAspectRatio(ratio: string);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* A component that can be used to show a playback
|
|
347
|
+
*/
|
|
348
|
+
declare class VLCPlayer extends PlaybackMethods<VLCPlayerProps> {}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* A component that renders a playback with additional
|
|
352
|
+
* features like fullscreen, controls, etc.
|
|
353
|
+
*/
|
|
354
|
+
declare class VlCPlayerView extends PlaybackMethods<any> {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#import "React/RCTView.h"
|
|
2
|
+
#if TARGET_OS_TV
|
|
3
|
+
#import <TVVLCKit/TVVLCKit.h>
|
|
4
|
+
#else
|
|
5
|
+
#import <MobileVLCKit/MobileVLCKit.h>
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
@class RCTEventDispatcher;
|
|
9
|
+
|
|
10
|
+
@interface RCTVLCPlayer : UIView <VLCCustomDialogRendererProtocol>
|
|
11
|
+
|
|
12
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoProgress;
|
|
13
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoPaused;
|
|
14
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoStopped;
|
|
15
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoBuffering;
|
|
16
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoPlaying;
|
|
17
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoEnded;
|
|
18
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoError;
|
|
19
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoOpen;
|
|
20
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoadStart;
|
|
21
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoad;
|
|
22
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onRecordingState;
|
|
23
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onSnapshot;
|
|
24
|
+
|
|
25
|
+
@property (nonatomic, strong) VLCDialogProvider *dialogProvider;
|
|
26
|
+
@property (nonatomic, assign) BOOL acceptInvalidCertificates;
|
|
27
|
+
|
|
28
|
+
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
|
|
29
|
+
- (void)setMuted:(BOOL)value;
|
|
30
|
+
- (void)setPlayInBackground:(BOOL)value;
|
|
31
|
+
- (void)setPlayWhenInactive:(BOOL)value;
|
|
32
|
+
- (void)startRecording:(NSString*)path;
|
|
33
|
+
- (void)stopRecording;
|
|
34
|
+
- (void)stopPlayer;
|
|
35
|
+
- (void)snapshot:(NSString*)path;
|
|
36
|
+
@end
|