expo-nodemediaclient 0.1.2 → 0.2.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/CHANGELOG.md +10 -0
- package/CLAUDE.md +55 -0
- package/README.md +203 -19
- package/android/build.gradle +6 -7
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodeMediaClientModule.kt +1 -1
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodePlayerView.kt +15 -20
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodePlayerViewModule.kt +58 -0
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodePublisherView.kt +175 -0
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodePublisherViewModule.kt +111 -0
- package/build/ExpoNodeMediaClientModule.js.map +1 -1
- package/build/ExpoNodePlayerView.d.ts +9 -3
- package/build/ExpoNodePlayerView.d.ts.map +1 -1
- package/build/ExpoNodePlayerView.js +3 -18
- package/build/ExpoNodePlayerView.js.map +1 -1
- package/build/ExpoNodePublisherView.d.ts +91 -0
- package/build/ExpoNodePublisherView.d.ts.map +1 -0
- package/build/ExpoNodePublisherView.js +44 -0
- package/build/ExpoNodePublisherView.js.map +1 -0
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -5
- package/build/index.js.map +1 -1
- package/expo-module.config.json +4 -2
- package/ios/ExpoNodeMediaClientModule.swift +1 -1
- package/ios/ExpoNodePlayerView.swift +76 -70
- package/ios/{ExpoNodePlayerModule.swift → ExpoNodePlayerViewModule.swift} +8 -6
- package/ios/ExpoNodePublisherView.swift +174 -0
- package/ios/ExpoNodePublisherViewModule.swift +114 -0
- package/ios/ExpoNodemediaclient.podspec +2 -3
- package/package.json +1 -1
- package/src/ExpoNodeMediaClientModule.tsx +1 -1
- package/src/ExpoNodePlayerView.tsx +12 -25
- package/src/ExpoNodePublisherView.tsx +99 -0
- package/src/index.ts +4 -7
- package/android/src/main/java/expo/modules/nodemediaclient/ExpoNodePlayerModule.kt +0 -60
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright (c) 2025 NodeMedia Technology Co., Ltd.
|
|
3
|
+
// Created by Chen Mingliang on 2025-07-23.
|
|
4
|
+
// All rights reserved.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import ExpoModulesCore
|
|
8
|
+
import NodeMediaClient
|
|
9
|
+
|
|
10
|
+
class ExpoNodePublisherView: ExpoView, NodePublisherDelegate {
|
|
11
|
+
private var _np: NodePublisher?
|
|
12
|
+
var url = ""
|
|
13
|
+
var cryptoKey = ""
|
|
14
|
+
var HWAccelEnable = true
|
|
15
|
+
var denoiseEnable = true
|
|
16
|
+
|
|
17
|
+
// EventDispatcher for sending events to JavaScript
|
|
18
|
+
var onEventCallback = EventDispatcher()
|
|
19
|
+
|
|
20
|
+
// Color and effect parameters
|
|
21
|
+
var colorStyleId: Int? {
|
|
22
|
+
didSet {
|
|
23
|
+
if let styleId = colorStyleId {
|
|
24
|
+
_np?.setEffectStyleWithId(styleId)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var colorStyleIntensity: Float? {
|
|
30
|
+
didSet {
|
|
31
|
+
if let intensity = colorStyleIntensity {
|
|
32
|
+
_np?.setEffectParameter("style", withIntensity: intensity)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var smoothskinIntensity: Float? {
|
|
38
|
+
didSet {
|
|
39
|
+
if let intensity = smoothskinIntensity {
|
|
40
|
+
_np?.setEffectParameter("smoothskin", withIntensity: intensity)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Audio parameters
|
|
46
|
+
var audioCodecid = Int(NMC_CODEC_ID_AAC)
|
|
47
|
+
var audioProfile = Int(NMC_PROFILE_AUTO)
|
|
48
|
+
var audioChannels = 2
|
|
49
|
+
var audioSamplingRate = 44100
|
|
50
|
+
var audioBitrate = 64000
|
|
51
|
+
|
|
52
|
+
// Video parameters
|
|
53
|
+
var videoCodecid = Int(NMC_CODEC_ID_H264)
|
|
54
|
+
var videoProfile = Int(NMC_PROFILE_AUTO)
|
|
55
|
+
var videoWidth = 720
|
|
56
|
+
var videoHeight = 1080
|
|
57
|
+
var videoFps = 30
|
|
58
|
+
var videoBitrate = 2000000
|
|
59
|
+
|
|
60
|
+
var keyFrameInterval = 2
|
|
61
|
+
var videoOrientation = 1
|
|
62
|
+
var cameraFrontMirror = true
|
|
63
|
+
|
|
64
|
+
var frontCamera: Bool? {
|
|
65
|
+
didSet {
|
|
66
|
+
if let fc = frontCamera, oldValue != frontCamera {
|
|
67
|
+
_np?.closeCamera()
|
|
68
|
+
_np?.openCamera(fc)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var zoomRatio: Float = 0.0{
|
|
74
|
+
didSet {
|
|
75
|
+
_np?.zoomRatio = zoomRatio
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var torchEnable: Bool = false {
|
|
80
|
+
didSet {
|
|
81
|
+
_np?.torchEnable = torchEnable
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var volume: Float = 1.0 {
|
|
86
|
+
didSet {
|
|
87
|
+
_np?.volume = volume
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
required init(appContext: AppContext? = nil) {
|
|
92
|
+
super.init(appContext: appContext)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override func didMoveToWindow() {
|
|
96
|
+
super.didMoveToWindow()
|
|
97
|
+
if window != nil {
|
|
98
|
+
// View attached to window
|
|
99
|
+
_np = NodePublisher(license: LICENSE_KEY)
|
|
100
|
+
applyAudioParams()
|
|
101
|
+
applyVideoParams()
|
|
102
|
+
_np?.nodePublisherDelegate = self
|
|
103
|
+
_np?.cameraFrontMirror = cameraFrontMirror
|
|
104
|
+
_np?.videoOrientation = videoOrientation
|
|
105
|
+
_np?.keyFrameInterval = keyFrameInterval
|
|
106
|
+
_np?.cryptoKey = cryptoKey
|
|
107
|
+
_np?.hwAccelEnable = HWAccelEnable
|
|
108
|
+
_np?.denoiseEnable = denoiseEnable
|
|
109
|
+
_np?.torchEnable = torchEnable
|
|
110
|
+
_np?.volume = volume
|
|
111
|
+
_np?.openCamera(frontCamera == true)
|
|
112
|
+
_np?.attach(self)
|
|
113
|
+
|
|
114
|
+
// Apply color and effect params if set
|
|
115
|
+
if let styleId = colorStyleId {
|
|
116
|
+
_np?.setEffectStyleWithId(styleId)
|
|
117
|
+
}
|
|
118
|
+
if let intensity = colorStyleIntensity {
|
|
119
|
+
_np?.setEffectParameter("style", withIntensity: intensity)
|
|
120
|
+
}
|
|
121
|
+
if let intensity = smoothskinIntensity {
|
|
122
|
+
_np?.setEffectParameter("smoothskin", withIntensity: intensity)
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// View detached from window
|
|
126
|
+
_np?.stop()
|
|
127
|
+
_np?.closeCamera()
|
|
128
|
+
_np?.detachView()
|
|
129
|
+
_np = nil
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private func applyAudioParams() {
|
|
134
|
+
_np?.setAudioParamWithCodec(audioCodecid, profile: audioProfile, samplerate: audioSamplingRate, channels: audioChannels, bitrate: audioBitrate)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private func applyVideoParams() {
|
|
138
|
+
_np?.setVideoParamWithCodec(videoCodecid, profile: videoProfile, width: videoWidth, height: videoHeight, fps: videoFps, bitrate: videoBitrate)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func start(u: String?) {
|
|
142
|
+
if let newUrl = u {
|
|
143
|
+
url = newUrl
|
|
144
|
+
}
|
|
145
|
+
_np?.start(url)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
func stop() {
|
|
149
|
+
_np?.stop()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
func setEffectParameter(key: String, value: Float) {
|
|
153
|
+
// Convert string to float for effect parameter
|
|
154
|
+
_np?.setEffectParameter(key, withIntensity: value)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
func setEffectStyle(style: Int) {
|
|
158
|
+
_np?.setEffectStyleWithId(style)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
func startFocusAndMeteringCenter() {
|
|
162
|
+
_np?.startFocusAndMeteringCenter()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// MARK: - NodePublisherDelegate
|
|
166
|
+
|
|
167
|
+
func onEventCallback(_ sender: Any, event: Int32, msg: String) {
|
|
168
|
+
onEventCallback([
|
|
169
|
+
"event": Int(event),
|
|
170
|
+
"msg": msg
|
|
171
|
+
])
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright (c) 2025 NodeMedia Technology Co., Ltd.
|
|
3
|
+
// Created by Chen Mingliang on 2025-07-23.
|
|
4
|
+
// All rights reserved.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import ExpoModulesCore
|
|
8
|
+
|
|
9
|
+
public class ExpoNodePublisherViewModule: Module {
|
|
10
|
+
public func definition() -> ModuleDefinition {
|
|
11
|
+
Name("ExpoNodePublisherView")
|
|
12
|
+
|
|
13
|
+
View(ExpoNodePublisherView.self) {
|
|
14
|
+
Events("onEventCallback")
|
|
15
|
+
|
|
16
|
+
Prop("url") { (view, url: String) in
|
|
17
|
+
view.url = url
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Prop("cryptoKey") { (view, key: String) in
|
|
21
|
+
view.cryptoKey = key
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Prop("HWAccelEnable") { (view, enable: Bool) in
|
|
25
|
+
view.HWAccelEnable = enable
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Audio parameters
|
|
29
|
+
Prop("audioParam") { (view, audioParam: [String: Int]) in
|
|
30
|
+
view.audioCodecid = audioParam["codecid"]!
|
|
31
|
+
view.audioProfile = audioParam["profile"]!
|
|
32
|
+
view.audioChannels = audioParam["channels"]!
|
|
33
|
+
view.audioSamplingRate = audioParam["samplingRate"]!
|
|
34
|
+
view.audioBitrate = audioParam["bitrate"]!
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Video parameters
|
|
38
|
+
Prop("videoParam") { (view, videoParam: [String: Int]) in
|
|
39
|
+
view.videoCodecid = videoParam["codecid"]!
|
|
40
|
+
view.videoProfile = videoParam["profile"]!
|
|
41
|
+
view.videoWidth = videoParam["width"]!
|
|
42
|
+
view.videoHeight = videoParam["height"]!
|
|
43
|
+
view.videoFps = videoParam["fps"]!
|
|
44
|
+
view.videoBitrate = videoParam["bitrate"]!
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Prop("keyFrameInterval") { (view, interval: Int) in
|
|
48
|
+
view.keyFrameInterval = interval
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Prop("videoOrientation") { (view, orientation: Int) in
|
|
52
|
+
view.videoOrientation = orientation
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
Prop("frontCamera") { (view, front: Bool) in
|
|
56
|
+
view.frontCamera = front
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Prop("cameraFrontMirror") { (view, mirror: Bool) in
|
|
60
|
+
view.cameraFrontMirror = mirror
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Prop("zoomRatio") { (view, ratio: Float) in
|
|
64
|
+
view.zoomRatio = ratio
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Prop("torchEnable") { (view, enable: Bool) in
|
|
68
|
+
view.torchEnable = enable
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Prop("denoiseEnable") { (view, enable: Bool) in
|
|
72
|
+
view.denoiseEnable = enable
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Prop("volume") { (view, volume: Float) in
|
|
76
|
+
view.volume = volume
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Color and effect parameters
|
|
80
|
+
Prop("colorStyleId") { (view, styleId: Int) in
|
|
81
|
+
view.colorStyleId = styleId
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Prop("colorStyleIntensity") { (view, intensity: Float) in
|
|
85
|
+
view.colorStyleIntensity = intensity
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Prop("smoothskinIntensity") { (view, intensity: Float) in
|
|
89
|
+
view.smoothskinIntensity = intensity
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Methods
|
|
93
|
+
AsyncFunction("start") { (view: ExpoNodePublisherView, url: String?) in
|
|
94
|
+
view.start(u: url)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
AsyncFunction("stop") { (view: ExpoNodePublisherView) in
|
|
98
|
+
view.stop()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
AsyncFunction("setEffectParameter") { (view: ExpoNodePublisherView, key: String, value: Float) in
|
|
102
|
+
view.setEffectParameter(key: key, value: value)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
AsyncFunction("setEffectStyle") { (view: ExpoNodePublisherView, style: Int) in
|
|
106
|
+
view.setEffectStyle(style: style)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
AsyncFunction("startFocusAndMeteringCenter") { (view: ExpoNodePublisherView) in
|
|
110
|
+
view.startFocusAndMeteringCenter()
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -14,13 +14,12 @@ Pod::Spec.new do |s|
|
|
|
14
14
|
:ios => '15.1',
|
|
15
15
|
:tvos => '15.1'
|
|
16
16
|
}
|
|
17
|
-
s.swift_version = '5.
|
|
17
|
+
s.swift_version = '5.9'
|
|
18
18
|
s.source = { git: 'https://github.com/NodeMedia/expo-nodemediaclient' }
|
|
19
19
|
s.static_framework = true
|
|
20
20
|
|
|
21
21
|
s.dependency 'ExpoModulesCore'
|
|
22
|
-
s.dependency 'NodeMediaClient', '~>
|
|
23
|
-
|
|
22
|
+
s.dependency 'NodeMediaClient', '~> 4.1.0'
|
|
24
23
|
# Swift/Objective-C compatibility
|
|
25
24
|
s.pod_target_xcconfig = {
|
|
26
25
|
'DEFINES_MODULE' => 'YES',
|
package/package.json
CHANGED
|
@@ -12,4 +12,4 @@ declare class ExpoNodeMediaClientModule extends NativeModule{
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// This call loads the native module object from the JSI.
|
|
15
|
-
export default requireNativeModule<ExpoNodeMediaClientModule>('ExpoNodeMediaClientModule');
|
|
15
|
+
export default requireNativeModule<ExpoNodeMediaClientModule>('ExpoNodeMediaClientModule');
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright (c) 2025 NodeMedia Technology Co., Ltd.
|
|
3
|
-
// Created by Chen Mingliang on 2025-07-22.
|
|
4
|
-
// All rights reserved.
|
|
5
|
-
//
|
|
6
1
|
|
|
7
|
-
import { ViewProps} from 'react-native';
|
|
2
|
+
import { ViewProps } from 'react-native';
|
|
8
3
|
import { requireNativeViewManager } from 'expo-modules-core';
|
|
9
|
-
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
10
4
|
|
|
11
5
|
export type NodePlayerRef = {
|
|
12
|
-
start: (url?:string) => void;
|
|
6
|
+
start: (url?: string) => void;
|
|
13
7
|
stop: () => void;
|
|
14
8
|
}
|
|
15
9
|
|
|
10
|
+
export type NodePlayerEventCallback = {
|
|
11
|
+
event: number;
|
|
12
|
+
msg: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
16
15
|
export type NodePlayerProps = {
|
|
17
|
-
ref?:
|
|
16
|
+
ref?: NodePlayerRef;
|
|
18
17
|
url?: string;
|
|
19
18
|
volume?: number;
|
|
20
19
|
cryptoKey?: string;
|
|
@@ -24,22 +23,10 @@ export type NodePlayerProps = {
|
|
|
24
23
|
HTTPUserAgent?: string;
|
|
25
24
|
RTSPTransport?: string;
|
|
26
25
|
HWAccelEnable?: boolean;
|
|
26
|
+
onEventCallback?: (event: { nativeEvent: NodePlayerEventCallback }) => void;
|
|
27
27
|
} & ViewProps;
|
|
28
28
|
|
|
29
29
|
const NativeView: React.ComponentType<NodePlayerProps> = requireNativeViewManager('ExpoNodePlayerView');
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
useImperativeHandle(ref, () => ({
|
|
35
|
-
start: (url?:string) => {
|
|
36
|
-
nativeRef.current?.start(url);
|
|
37
|
-
},
|
|
38
|
-
stop: () => {
|
|
39
|
-
nativeRef.current?.stop();
|
|
40
|
-
}
|
|
41
|
-
}));
|
|
42
|
-
|
|
43
|
-
return <NativeView ref={nativeRef} {...props} />;
|
|
44
|
-
});
|
|
45
|
-
|
|
30
|
+
export default function ExpoNodePlayerView(props: NodePlayerProps) {
|
|
31
|
+
return <NativeView {...props} />;
|
|
32
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
|
|
2
|
+
import { ViewProps } from 'react-native';
|
|
3
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
4
|
+
|
|
5
|
+
export type NodePublisherRef = {
|
|
6
|
+
start: (url?: string) => Promise<void>;
|
|
7
|
+
stop: () => Promise<void>;
|
|
8
|
+
setEffectParameter: (key: string, value: number) => Promise<void>;
|
|
9
|
+
setEffectStyle: (style: number) => Promise<void>;
|
|
10
|
+
startFocusAndMeteringCenter:() => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type NodePublisherEventCallback = {
|
|
14
|
+
event: number;
|
|
15
|
+
msg: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type AudioParam = {
|
|
19
|
+
codecid?: number;
|
|
20
|
+
profile?: number;
|
|
21
|
+
samplingRate?: number;
|
|
22
|
+
channels?: number;
|
|
23
|
+
bitrate?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type VideoParam = {
|
|
27
|
+
codecid?: number;
|
|
28
|
+
profile?: number;
|
|
29
|
+
width?: number;
|
|
30
|
+
height?: number;
|
|
31
|
+
fps?: number;
|
|
32
|
+
bitrate?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type NodePublisherProps = {
|
|
36
|
+
ref?: NodePublisherRef;
|
|
37
|
+
url?: string;
|
|
38
|
+
cryptoKey?: string;
|
|
39
|
+
audioParam?: AudioParam
|
|
40
|
+
videoParam?: VideoParam;
|
|
41
|
+
keyFrameInterval?: number;
|
|
42
|
+
videoOrientation?: number;
|
|
43
|
+
frontCamera?: boolean;
|
|
44
|
+
cameraFrontMirror?: boolean;
|
|
45
|
+
zoomRatio?: number;
|
|
46
|
+
volume?: number;
|
|
47
|
+
torchEnable?: boolean;
|
|
48
|
+
HWAccelEnable?: boolean;
|
|
49
|
+
denoiseEnable?: boolean;
|
|
50
|
+
colorStyleId?: number;
|
|
51
|
+
colorStyleIntensity?: number;
|
|
52
|
+
smoothskinIntensity?: number;
|
|
53
|
+
onEventCallback?: (event: { nativeEvent: NodePublisherEventCallback }) => void;
|
|
54
|
+
} & ViewProps;
|
|
55
|
+
|
|
56
|
+
const NativeView: React.ComponentType<NodePublisherProps> = requireNativeViewManager('ExpoNodePublisherView');
|
|
57
|
+
function ExpoNodePublisherView(props: NodePublisherProps) {
|
|
58
|
+
return <NativeView {...props} />;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
ExpoNodePublisherView.NMC_CODEC_ID_H264 = 27;
|
|
62
|
+
ExpoNodePublisherView.NMC_CODEC_ID_H265 = 173;
|
|
63
|
+
ExpoNodePublisherView.NMC_CODEC_ID_AAC = 86018;
|
|
64
|
+
ExpoNodePublisherView.NMC_CODEC_ID_OPUS = 86076;
|
|
65
|
+
ExpoNodePublisherView.NMC_CODEC_ID_PCMA = 65543;
|
|
66
|
+
ExpoNodePublisherView.NMC_CODEC_ID_PCMU = 65542;
|
|
67
|
+
ExpoNodePublisherView.NMC_PROFILE_AUTO = 0;
|
|
68
|
+
ExpoNodePublisherView.NMC_PROFILE_H264_BASELINE = 66;
|
|
69
|
+
ExpoNodePublisherView.NMC_PROFILE_H264_MAIN = 77;
|
|
70
|
+
ExpoNodePublisherView.NMC_PROFILE_H264_HIGH = 100;
|
|
71
|
+
ExpoNodePublisherView.NMC_PROFILE_H265_MAIN = 1;
|
|
72
|
+
ExpoNodePublisherView.NMC_PROFILE_AAC_LC = 1;
|
|
73
|
+
ExpoNodePublisherView.NMC_PROFILE_AAC_HE = 4;
|
|
74
|
+
ExpoNodePublisherView.NMC_PROFILE_AAC_HE_V2 = 28;
|
|
75
|
+
ExpoNodePublisherView.VIDEO_ORIENTATION_PORTRAIT = 1;
|
|
76
|
+
ExpoNodePublisherView.VIDEO_ORIENTATION_LANDSCAPE_RIGHT = 3;
|
|
77
|
+
ExpoNodePublisherView.VIDEO_ORIENTATION_LANDSCAPE_LEFT = 4;
|
|
78
|
+
ExpoNodePublisherView.FLAG_AF = 1;
|
|
79
|
+
ExpoNodePublisherView.FLAG_AE = 2;
|
|
80
|
+
ExpoNodePublisherView.FLAG_AWB = 4;
|
|
81
|
+
ExpoNodePublisherView.NMC_DEVICE_TYPE_WideAngleCamera = 0;
|
|
82
|
+
ExpoNodePublisherView.NMC_DEVICE_TYPE_TelephotoCamera = 1;
|
|
83
|
+
ExpoNodePublisherView.NMC_DEVICE_TYPE_UltraWideCamera = 2;
|
|
84
|
+
ExpoNodePublisherView.NMC_DEVICE_TYPE_DualCamera = 3;
|
|
85
|
+
ExpoNodePublisherView.NMC_DEVICE_TYPE_TripleCamera = 4;
|
|
86
|
+
ExpoNodePublisherView.EFFECTOR_BRIGHTNESS = "brightness";
|
|
87
|
+
ExpoNodePublisherView.EFFECTOR_CONTRAST = "contrast";
|
|
88
|
+
ExpoNodePublisherView.EFFECTOR_SATURATION = "saturation";
|
|
89
|
+
ExpoNodePublisherView.EFFECTOR_SHARPEN = "sharpen";
|
|
90
|
+
ExpoNodePublisherView.EFFECTOR_SMOOTHSKIN = "smoothskin";
|
|
91
|
+
ExpoNodePublisherView.EFFECTOR_STYLE = "style";
|
|
92
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_ORIGINAL = 0;
|
|
93
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_ENHANCED = 1;
|
|
94
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_FAIRSKIN = 2;
|
|
95
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_COOL = 3;
|
|
96
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_FILM = 4;
|
|
97
|
+
ExpoNodePublisherView.EFFECTOR_STYLE_ID_BOOST = 5;
|
|
98
|
+
|
|
99
|
+
export default ExpoNodePublisherView;
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Created by Chen Mingliang on 2025-07-22.
|
|
4
|
-
// All rights reserved.
|
|
5
|
-
//
|
|
6
|
-
|
|
1
|
+
// Reexport the native module. On web, it will be resolved to ExpoNodemediaclientModule.web.ts
|
|
2
|
+
// and on native platforms to ExpoNodemediaclientModule.ts
|
|
7
3
|
export { default as NodeMediaClient } from './ExpoNodeMediaClientModule';
|
|
8
|
-
export { default as NodePlayer, NodePlayerRef, NodePlayerProps } from './ExpoNodePlayerView';
|
|
4
|
+
export { default as NodePlayer, NodePlayerRef, NodePlayerProps, NodePlayerEventCallback } from './ExpoNodePlayerView';
|
|
5
|
+
export { default as NodePublisher, AudioParam, VideoParam, NodePublisherRef, NodePublisherProps, NodePublisherEventCallback } from './ExpoNodePublisherView';
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright (c) 2025 NodeMedia Technology Co., Ltd.
|
|
3
|
-
// Created by Chen Mingliang on 2025-07-22.
|
|
4
|
-
// All rights reserved.
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
package expo.modules.nodemediaclient
|
|
8
|
-
|
|
9
|
-
import expo.modules.kotlin.modules.Module
|
|
10
|
-
import expo.modules.kotlin.modules.ModuleDefinition
|
|
11
|
-
|
|
12
|
-
class ExpoNodePlayerModule : Module() {
|
|
13
|
-
override fun definition() = ModuleDefinition {
|
|
14
|
-
Name("ExpoNodePlayerView")
|
|
15
|
-
|
|
16
|
-
View(ExpoNodePlayerView::class) {
|
|
17
|
-
Prop("url") { view: ExpoNodePlayerView, url: String ->
|
|
18
|
-
view.url = url
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
Prop("volume") { view: ExpoNodePlayerView, volume: Float ->
|
|
22
|
-
view.volume = volume
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
Prop("cryptoKey") { view: ExpoNodePlayerView, cryptoKey: String ->
|
|
26
|
-
view.cryptoKey = cryptoKey
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
Prop("scaleMode") { view: ExpoNodePlayerView, scaleMode: Int ->
|
|
30
|
-
view.scaleMode = scaleMode
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
Prop("bufferTime") { view: ExpoNodePlayerView, bufferTime: Int ->
|
|
34
|
-
view.bufferTime = bufferTime
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
Prop("HTTPReferer") { view: ExpoNodePlayerView, HTTPReferer: String ->
|
|
38
|
-
view.HTTPReferer = HTTPReferer
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
Prop("HTTPUserAgent") { view: ExpoNodePlayerView, HTTPUserAgent: String ->
|
|
42
|
-
view.HTTPUserAgent = HTTPUserAgent
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
Prop("RTSPTransport") { view: ExpoNodePlayerView, RTSPTransport: String ->
|
|
46
|
-
view.RTSPTransport = RTSPTransport
|
|
47
|
-
}
|
|
48
|
-
Prop("HWAccelEnable") { view: ExpoNodePlayerView, HWAccelEnable: Boolean ->
|
|
49
|
-
view.HWAccelEnable = HWAccelEnable
|
|
50
|
-
}
|
|
51
|
-
AsyncFunction("start") { view: ExpoNodePlayerView, url: String? ->
|
|
52
|
-
view.start(url)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
AsyncFunction("stop") { view: ExpoNodePlayerView ->
|
|
56
|
-
view.stop()
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|