@abdurrahman-dev/react-native-ivs-broadcast 0.1.0
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.
Potentially problematic release.
This version of @abdurrahman-dev/react-native-ivs-broadcast might be problematic. Click here for more details.
- package/LICENSE +22 -0
- package/README.md +296 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +13 -0
- package/android/src/main/java/com/reactnativeivsbroadcast/IVSBroadcastModule.kt +433 -0
- package/android/src/main/java/com/reactnativeivsbroadcast/IVSBroadcastPackage.kt +17 -0
- package/ios/IVSBroadcast.podspec +24 -0
- package/ios/IVSBroadcastModule.h +7 -0
- package/ios/IVSBroadcastModule.m +513 -0
- package/lib/index.d.ts +78 -0
- package/lib/index.js +234 -0
- package/lib/types.d.ts +55 -0
- package/lib/types.js +2 -0
- package/package.json +57 -0
- package/src/index.ts +273 -0
- package/src/types.ts +72 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
const react_native_1 = require("react-native");
|
|
18
|
+
const { IVSBroadcastModule } = react_native_1.NativeModules;
|
|
19
|
+
if (!IVSBroadcastModule) {
|
|
20
|
+
throw new Error("IVSBroadcastModule native module is not available. Make sure you have properly linked the module.");
|
|
21
|
+
}
|
|
22
|
+
const eventEmitter = new react_native_1.NativeEventEmitter(IVSBroadcastModule);
|
|
23
|
+
class IVSBroadcast {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.listeners = new Map();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Yeni bir broadcast session oluşturur
|
|
29
|
+
*/
|
|
30
|
+
async createSession(config) {
|
|
31
|
+
if (!config.rtmpUrl) {
|
|
32
|
+
throw new Error("RTMP URL is required");
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const sessionId = await IVSBroadcastModule.createSession(config);
|
|
36
|
+
return { sessionId };
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`Failed to create session: ${error.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Broadcast'i başlatır
|
|
44
|
+
*/
|
|
45
|
+
async startBroadcast(sessionId) {
|
|
46
|
+
try {
|
|
47
|
+
await IVSBroadcastModule.startBroadcast(sessionId);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`Failed to start broadcast: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Broadcast'i durdurur
|
|
55
|
+
*/
|
|
56
|
+
async stopBroadcast(sessionId) {
|
|
57
|
+
try {
|
|
58
|
+
await IVSBroadcastModule.stopBroadcast(sessionId);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`Failed to stop broadcast: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Broadcast'i duraklatır
|
|
66
|
+
*/
|
|
67
|
+
async pauseBroadcast(sessionId) {
|
|
68
|
+
try {
|
|
69
|
+
await IVSBroadcastModule.pauseBroadcast(sessionId);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw new Error(`Failed to pause broadcast: ${error.message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Duraklatılmış broadcast'i devam ettirir
|
|
77
|
+
*/
|
|
78
|
+
async resumeBroadcast(sessionId) {
|
|
79
|
+
try {
|
|
80
|
+
await IVSBroadcastModule.resumeBroadcast(sessionId);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new Error(`Failed to resume broadcast: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Broadcast session'ı yok eder
|
|
88
|
+
*/
|
|
89
|
+
async destroySession(sessionId) {
|
|
90
|
+
try {
|
|
91
|
+
await IVSBroadcastModule.destroySession(sessionId);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw new Error(`Failed to destroy session: ${error.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Broadcast durumunu alır
|
|
99
|
+
*/
|
|
100
|
+
async getState(sessionId) {
|
|
101
|
+
try {
|
|
102
|
+
return await IVSBroadcastModule.getState(sessionId);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
throw new Error(`Failed to get state: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Kamera pozisyonunu değiştirir
|
|
110
|
+
*/
|
|
111
|
+
async switchCamera(sessionId) {
|
|
112
|
+
try {
|
|
113
|
+
await IVSBroadcastModule.switchCamera(sessionId);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Failed to switch camera: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Kamera pozisyonunu ayarlar
|
|
121
|
+
*/
|
|
122
|
+
async setCameraPosition(sessionId, position) {
|
|
123
|
+
try {
|
|
124
|
+
await IVSBroadcastModule.setCameraPosition(sessionId, position);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw new Error(`Failed to set camera position: ${error.message}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Mikrofonu açıp kapatır
|
|
132
|
+
*/
|
|
133
|
+
async setMuted(sessionId, muted) {
|
|
134
|
+
try {
|
|
135
|
+
await IVSBroadcastModule.setMuted(sessionId, muted);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to set muted state: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Mikrofon durumunu alır
|
|
143
|
+
*/
|
|
144
|
+
async isMuted(sessionId) {
|
|
145
|
+
try {
|
|
146
|
+
return await IVSBroadcastModule.isMuted(sessionId);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw new Error(`Failed to get muted state: ${error.message}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Video konfigürasyonunu günceller
|
|
154
|
+
*/
|
|
155
|
+
async updateVideoConfig(sessionId, config) {
|
|
156
|
+
try {
|
|
157
|
+
await IVSBroadcastModule.updateVideoConfig(sessionId, config);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
throw new Error(`Failed to update video config: ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Audio konfigürasyonunu günceller
|
|
165
|
+
*/
|
|
166
|
+
async updateAudioConfig(sessionId, config) {
|
|
167
|
+
try {
|
|
168
|
+
await IVSBroadcastModule.updateAudioConfig(sessionId, config);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw new Error(`Failed to update audio config: ${error.message}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
addListener(eventType, callback) {
|
|
175
|
+
if (!this.listeners.has(eventType)) {
|
|
176
|
+
this.listeners.set(eventType, []);
|
|
177
|
+
}
|
|
178
|
+
this.listeners.get(eventType).push(callback);
|
|
179
|
+
const subscription = eventEmitter.addListener(eventType, (data) => {
|
|
180
|
+
const callbacks = this.listeners.get(eventType);
|
|
181
|
+
if (callbacks) {
|
|
182
|
+
callbacks.forEach((cb) => cb(data));
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
// Cleanup fonksiyonunu döndür
|
|
186
|
+
return () => {
|
|
187
|
+
subscription.remove();
|
|
188
|
+
const callbacks = this.listeners.get(eventType);
|
|
189
|
+
if (callbacks) {
|
|
190
|
+
const index = callbacks.indexOf(callback);
|
|
191
|
+
if (index > -1) {
|
|
192
|
+
callbacks.splice(index, 1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Event listener'ı kaldırır
|
|
199
|
+
*/
|
|
200
|
+
removeListener(eventType, callback) {
|
|
201
|
+
const callbacks = this.listeners.get(eventType);
|
|
202
|
+
if (callbacks) {
|
|
203
|
+
if (callback) {
|
|
204
|
+
const index = callbacks.indexOf(callback);
|
|
205
|
+
if (index > -1) {
|
|
206
|
+
callbacks.splice(index, 1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
this.listeners.delete(eventType);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
eventEmitter.removeAllListeners(eventType);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Tüm listener'ları temizler
|
|
217
|
+
*/
|
|
218
|
+
removeAllListeners(eventType) {
|
|
219
|
+
if (eventType) {
|
|
220
|
+
this.listeners.delete(eventType);
|
|
221
|
+
eventEmitter.removeAllListeners(eventType);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.listeners.clear();
|
|
225
|
+
// Tüm event type'ları için listener'ları temizle
|
|
226
|
+
this.listeners.forEach((_, type) => {
|
|
227
|
+
eventEmitter.removeAllListeners(type);
|
|
228
|
+
});
|
|
229
|
+
this.listeners.clear();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.default = new IVSBroadcast();
|
|
234
|
+
__exportStar(require("./types"), exports);
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface IVSBroadcastConfig {
|
|
2
|
+
rtmpUrl: string;
|
|
3
|
+
streamKey?: string;
|
|
4
|
+
videoConfig?: VideoConfig;
|
|
5
|
+
audioConfig?: AudioConfig;
|
|
6
|
+
}
|
|
7
|
+
export interface VideoConfig {
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
bitrate?: number;
|
|
11
|
+
fps?: number;
|
|
12
|
+
targetFps?: number;
|
|
13
|
+
keyframeInterval?: number;
|
|
14
|
+
encoder?: 'hardware' | 'software';
|
|
15
|
+
}
|
|
16
|
+
export interface AudioConfig {
|
|
17
|
+
bitrate?: number;
|
|
18
|
+
sampleRate?: number;
|
|
19
|
+
channels?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface IVSBroadcastSession {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
}
|
|
24
|
+
export interface BroadcastState {
|
|
25
|
+
isBroadcasting: boolean;
|
|
26
|
+
isPaused: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface CameraPosition {
|
|
30
|
+
position: 'front' | 'back';
|
|
31
|
+
}
|
|
32
|
+
export interface PreviewViewProps {
|
|
33
|
+
style?: any;
|
|
34
|
+
}
|
|
35
|
+
export type BroadcastEventType = 'onStateChanged' | 'onError' | 'onNetworkHealth' | 'onAudioStats' | 'onVideoStats';
|
|
36
|
+
export interface BroadcastEvent {
|
|
37
|
+
type: BroadcastEventType;
|
|
38
|
+
data?: any;
|
|
39
|
+
}
|
|
40
|
+
export interface NetworkHealth {
|
|
41
|
+
networkQuality: 'excellent' | 'good' | 'fair' | 'poor';
|
|
42
|
+
uplinkBandwidth?: number;
|
|
43
|
+
rtt?: number;
|
|
44
|
+
}
|
|
45
|
+
export interface AudioStats {
|
|
46
|
+
bitrate: number;
|
|
47
|
+
sampleRate: number;
|
|
48
|
+
channels: number;
|
|
49
|
+
}
|
|
50
|
+
export interface VideoStats {
|
|
51
|
+
bitrate: number;
|
|
52
|
+
fps: number;
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
}
|
package/lib/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@abdurrahman-dev/react-native-ivs-broadcast",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React Native bridge for Amazon IVS Broadcast SDK (Android 1.37.1, iOS 1.37.0)",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepare": "npm run build",
|
|
10
|
+
"lint": "eslint . --ext .ts,.tsx"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"react-native",
|
|
14
|
+
"amazon-ivs",
|
|
15
|
+
"ivs-broadcast",
|
|
16
|
+
"video-streaming",
|
|
17
|
+
"broadcast",
|
|
18
|
+
"aws"
|
|
19
|
+
],
|
|
20
|
+
"author": "",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/abdurrahman-dev/react-native-ivs-broadcast.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/abdurrahman-dev/react-native-ivs-broadcast/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/abdurrahman-dev/react-native-ivs-broadcast#readme",
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react-native": ">=0.60.0"
|
|
32
|
+
},
|
|
33
|
+
"react-native": {
|
|
34
|
+
"android": {
|
|
35
|
+
"sourceDir": "./android",
|
|
36
|
+
"packageImportPath": "import com.reactnativeivsbroadcast.IVSBroadcastPackage;"
|
|
37
|
+
},
|
|
38
|
+
"ios": {
|
|
39
|
+
"podspecPath": "./ios/IVSBroadcast.podspec"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/react-native": "^0.70.0",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
|
45
|
+
"@typescript-eslint/parser": "^5.0.0",
|
|
46
|
+
"eslint": "^8.0.0",
|
|
47
|
+
"typescript": "^4.9.0"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"android/",
|
|
51
|
+
"ios/",
|
|
52
|
+
"lib/",
|
|
53
|
+
"src/",
|
|
54
|
+
"README.md",
|
|
55
|
+
"LICENSE"
|
|
56
|
+
]
|
|
57
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { NativeModules, NativeEventEmitter, Platform } from "react-native";
|
|
2
|
+
import type {
|
|
3
|
+
IVSBroadcastConfig,
|
|
4
|
+
IVSBroadcastSession,
|
|
5
|
+
BroadcastState,
|
|
6
|
+
CameraPosition,
|
|
7
|
+
BroadcastEvent,
|
|
8
|
+
NetworkHealth,
|
|
9
|
+
AudioStats,
|
|
10
|
+
VideoStats,
|
|
11
|
+
VideoConfig,
|
|
12
|
+
AudioConfig,
|
|
13
|
+
} from "./types";
|
|
14
|
+
|
|
15
|
+
const { IVSBroadcastModule } = NativeModules;
|
|
16
|
+
|
|
17
|
+
if (!IVSBroadcastModule) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"IVSBroadcastModule native module is not available. Make sure you have properly linked the module."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const eventEmitter = new NativeEventEmitter(IVSBroadcastModule);
|
|
24
|
+
|
|
25
|
+
class IVSBroadcast {
|
|
26
|
+
private listeners: Map<string, Array<(data: any) => void>> = new Map();
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Yeni bir broadcast session oluşturur
|
|
30
|
+
*/
|
|
31
|
+
async createSession(
|
|
32
|
+
config: IVSBroadcastConfig
|
|
33
|
+
): Promise<IVSBroadcastSession> {
|
|
34
|
+
if (!config.rtmpUrl) {
|
|
35
|
+
throw new Error("RTMP URL is required");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const sessionId = await IVSBroadcastModule.createSession(config);
|
|
40
|
+
return { sessionId };
|
|
41
|
+
} catch (error: any) {
|
|
42
|
+
throw new Error(`Failed to create session: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Broadcast'i başlatır
|
|
48
|
+
*/
|
|
49
|
+
async startBroadcast(sessionId: string): Promise<void> {
|
|
50
|
+
try {
|
|
51
|
+
await IVSBroadcastModule.startBroadcast(sessionId);
|
|
52
|
+
} catch (error: any) {
|
|
53
|
+
throw new Error(`Failed to start broadcast: ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Broadcast'i durdurur
|
|
59
|
+
*/
|
|
60
|
+
async stopBroadcast(sessionId: string): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
await IVSBroadcastModule.stopBroadcast(sessionId);
|
|
63
|
+
} catch (error: any) {
|
|
64
|
+
throw new Error(`Failed to stop broadcast: ${error.message}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Broadcast'i duraklatır
|
|
70
|
+
*/
|
|
71
|
+
async pauseBroadcast(sessionId: string): Promise<void> {
|
|
72
|
+
try {
|
|
73
|
+
await IVSBroadcastModule.pauseBroadcast(sessionId);
|
|
74
|
+
} catch (error: any) {
|
|
75
|
+
throw new Error(`Failed to pause broadcast: ${error.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Duraklatılmış broadcast'i devam ettirir
|
|
81
|
+
*/
|
|
82
|
+
async resumeBroadcast(sessionId: string): Promise<void> {
|
|
83
|
+
try {
|
|
84
|
+
await IVSBroadcastModule.resumeBroadcast(sessionId);
|
|
85
|
+
} catch (error: any) {
|
|
86
|
+
throw new Error(`Failed to resume broadcast: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Broadcast session'ı yok eder
|
|
92
|
+
*/
|
|
93
|
+
async destroySession(sessionId: string): Promise<void> {
|
|
94
|
+
try {
|
|
95
|
+
await IVSBroadcastModule.destroySession(sessionId);
|
|
96
|
+
} catch (error: any) {
|
|
97
|
+
throw new Error(`Failed to destroy session: ${error.message}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Broadcast durumunu alır
|
|
103
|
+
*/
|
|
104
|
+
async getState(sessionId: string): Promise<BroadcastState> {
|
|
105
|
+
try {
|
|
106
|
+
return await IVSBroadcastModule.getState(sessionId);
|
|
107
|
+
} catch (error: any) {
|
|
108
|
+
throw new Error(`Failed to get state: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Kamera pozisyonunu değiştirir
|
|
114
|
+
*/
|
|
115
|
+
async switchCamera(sessionId: string): Promise<void> {
|
|
116
|
+
try {
|
|
117
|
+
await IVSBroadcastModule.switchCamera(sessionId);
|
|
118
|
+
} catch (error: any) {
|
|
119
|
+
throw new Error(`Failed to switch camera: ${error.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Kamera pozisyonunu ayarlar
|
|
125
|
+
*/
|
|
126
|
+
async setCameraPosition(
|
|
127
|
+
sessionId: string,
|
|
128
|
+
position: "front" | "back"
|
|
129
|
+
): Promise<void> {
|
|
130
|
+
try {
|
|
131
|
+
await IVSBroadcastModule.setCameraPosition(sessionId, position);
|
|
132
|
+
} catch (error: any) {
|
|
133
|
+
throw new Error(`Failed to set camera position: ${error.message}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Mikrofonu açıp kapatır
|
|
139
|
+
*/
|
|
140
|
+
async setMuted(sessionId: string, muted: boolean): Promise<void> {
|
|
141
|
+
try {
|
|
142
|
+
await IVSBroadcastModule.setMuted(sessionId, muted);
|
|
143
|
+
} catch (error: any) {
|
|
144
|
+
throw new Error(`Failed to set muted state: ${error.message}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Mikrofon durumunu alır
|
|
150
|
+
*/
|
|
151
|
+
async isMuted(sessionId: string): Promise<boolean> {
|
|
152
|
+
try {
|
|
153
|
+
return await IVSBroadcastModule.isMuted(sessionId);
|
|
154
|
+
} catch (error: any) {
|
|
155
|
+
throw new Error(`Failed to get muted state: ${error.message}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Video konfigürasyonunu günceller
|
|
161
|
+
*/
|
|
162
|
+
async updateVideoConfig(
|
|
163
|
+
sessionId: string,
|
|
164
|
+
config: VideoConfig
|
|
165
|
+
): Promise<void> {
|
|
166
|
+
try {
|
|
167
|
+
await IVSBroadcastModule.updateVideoConfig(sessionId, config);
|
|
168
|
+
} catch (error: any) {
|
|
169
|
+
throw new Error(`Failed to update video config: ${error.message}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Audio konfigürasyonunu günceller
|
|
175
|
+
*/
|
|
176
|
+
async updateAudioConfig(
|
|
177
|
+
sessionId: string,
|
|
178
|
+
config: AudioConfig
|
|
179
|
+
): Promise<void> {
|
|
180
|
+
try {
|
|
181
|
+
await IVSBroadcastModule.updateAudioConfig(sessionId, config);
|
|
182
|
+
} catch (error: any) {
|
|
183
|
+
throw new Error(`Failed to update audio config: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Event listener ekler
|
|
189
|
+
*/
|
|
190
|
+
addListener(
|
|
191
|
+
eventType: "onStateChanged",
|
|
192
|
+
callback: (state: BroadcastState) => void
|
|
193
|
+
): void;
|
|
194
|
+
addListener(
|
|
195
|
+
eventType: "onError",
|
|
196
|
+
callback: (error: { message: string; code?: string }) => void
|
|
197
|
+
): void;
|
|
198
|
+
addListener(
|
|
199
|
+
eventType: "onNetworkHealth",
|
|
200
|
+
callback: (health: NetworkHealth) => void
|
|
201
|
+
): void;
|
|
202
|
+
addListener(
|
|
203
|
+
eventType: "onAudioStats",
|
|
204
|
+
callback: (stats: AudioStats) => void
|
|
205
|
+
): void;
|
|
206
|
+
addListener(
|
|
207
|
+
eventType: "onVideoStats",
|
|
208
|
+
callback: (stats: VideoStats) => void
|
|
209
|
+
): void;
|
|
210
|
+
addListener(eventType: string, callback: (data: any) => void): () => void {
|
|
211
|
+
if (!this.listeners.has(eventType)) {
|
|
212
|
+
this.listeners.set(eventType, []);
|
|
213
|
+
}
|
|
214
|
+
this.listeners.get(eventType)!.push(callback);
|
|
215
|
+
|
|
216
|
+
const subscription = eventEmitter.addListener(eventType, (data) => {
|
|
217
|
+
const callbacks = this.listeners.get(eventType);
|
|
218
|
+
if (callbacks) {
|
|
219
|
+
callbacks.forEach((cb) => cb(data));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Cleanup fonksiyonunu döndür
|
|
224
|
+
return () => {
|
|
225
|
+
subscription.remove();
|
|
226
|
+
const callbacks = this.listeners.get(eventType);
|
|
227
|
+
if (callbacks) {
|
|
228
|
+
const index = callbacks.indexOf(callback);
|
|
229
|
+
if (index > -1) {
|
|
230
|
+
callbacks.splice(index, 1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Event listener'ı kaldırır
|
|
238
|
+
*/
|
|
239
|
+
removeListener(eventType: string, callback?: (data: any) => void): void {
|
|
240
|
+
const callbacks = this.listeners.get(eventType);
|
|
241
|
+
if (callbacks) {
|
|
242
|
+
if (callback) {
|
|
243
|
+
const index = callbacks.indexOf(callback);
|
|
244
|
+
if (index > -1) {
|
|
245
|
+
callbacks.splice(index, 1);
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
this.listeners.delete(eventType);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
eventEmitter.removeAllListeners(eventType);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Tüm listener'ları temizler
|
|
256
|
+
*/
|
|
257
|
+
removeAllListeners(eventType?: string): void {
|
|
258
|
+
if (eventType) {
|
|
259
|
+
this.listeners.delete(eventType);
|
|
260
|
+
eventEmitter.removeAllListeners(eventType);
|
|
261
|
+
} else {
|
|
262
|
+
this.listeners.clear();
|
|
263
|
+
// Tüm event type'ları için listener'ları temizle
|
|
264
|
+
this.listeners.forEach((_, type) => {
|
|
265
|
+
eventEmitter.removeAllListeners(type);
|
|
266
|
+
});
|
|
267
|
+
this.listeners.clear();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export default new IVSBroadcast();
|
|
273
|
+
export * from "./types";
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface IVSBroadcastConfig {
|
|
2
|
+
rtmpUrl: string;
|
|
3
|
+
streamKey?: string;
|
|
4
|
+
videoConfig?: VideoConfig;
|
|
5
|
+
audioConfig?: AudioConfig;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface VideoConfig {
|
|
9
|
+
width?: number;
|
|
10
|
+
height?: number;
|
|
11
|
+
bitrate?: number;
|
|
12
|
+
fps?: number;
|
|
13
|
+
targetFps?: number;
|
|
14
|
+
keyframeInterval?: number;
|
|
15
|
+
encoder?: 'hardware' | 'software';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AudioConfig {
|
|
19
|
+
bitrate?: number;
|
|
20
|
+
sampleRate?: number;
|
|
21
|
+
channels?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IVSBroadcastSession {
|
|
25
|
+
sessionId: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface BroadcastState {
|
|
29
|
+
isBroadcasting: boolean;
|
|
30
|
+
isPaused: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CameraPosition {
|
|
35
|
+
position: 'front' | 'back';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PreviewViewProps {
|
|
39
|
+
style?: any;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type BroadcastEventType =
|
|
43
|
+
| 'onStateChanged'
|
|
44
|
+
| 'onError'
|
|
45
|
+
| 'onNetworkHealth'
|
|
46
|
+
| 'onAudioStats'
|
|
47
|
+
| 'onVideoStats';
|
|
48
|
+
|
|
49
|
+
export interface BroadcastEvent {
|
|
50
|
+
type: BroadcastEventType;
|
|
51
|
+
data?: any;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface NetworkHealth {
|
|
55
|
+
networkQuality: 'excellent' | 'good' | 'fair' | 'poor';
|
|
56
|
+
uplinkBandwidth?: number;
|
|
57
|
+
rtt?: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface AudioStats {
|
|
61
|
+
bitrate: number;
|
|
62
|
+
sampleRate: number;
|
|
63
|
+
channels: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface VideoStats {
|
|
67
|
+
bitrate: number;
|
|
68
|
+
fps: number;
|
|
69
|
+
width: number;
|
|
70
|
+
height: number;
|
|
71
|
+
}
|
|
72
|
+
|