rnww-plugin-camera 1.0.5 → 1.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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 카메라 브릿지 핸들러
|
|
3
3
|
* 의존성 주입을 통해 동작하는 순수한 브릿지 로직
|
|
4
4
|
*/
|
|
5
|
-
import type { IBridge, IPlatform
|
|
5
|
+
import type { IBridge, IPlatform } from '../types';
|
|
6
6
|
/**
|
|
7
7
|
* 카메라 브릿지 설정
|
|
8
8
|
*/
|
|
@@ -15,11 +15,6 @@ export interface CameraBridgeConfig {
|
|
|
15
15
|
* 플랫폼 구현체
|
|
16
16
|
*/
|
|
17
17
|
platform: IPlatform;
|
|
18
|
-
/**
|
|
19
|
-
* 카메라 모듈 인스턴스
|
|
20
|
-
* 이 패키지의 src/module/index.ts를 직접 전달
|
|
21
|
-
*/
|
|
22
|
-
cameraModule: ICameraModule;
|
|
23
18
|
/**
|
|
24
19
|
* 로거 (선택적)
|
|
25
20
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"camera-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/camera-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,OAAO,EACP,SAAS,
|
|
1
|
+
{"version":3,"file":"camera-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/camera-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,OAAO,EACP,SAAS,EACZ,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE;QACL,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAC9B,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAC/B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;KACnC,CAAC;CACL;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,kBAAkB,SA+NhE,CAAC"}
|
|
@@ -3,14 +3,48 @@
|
|
|
3
3
|
* 카메라 브릿지 핸들러
|
|
4
4
|
* 의존성 주입을 통해 동작하는 순수한 브릿지 로직
|
|
5
5
|
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
6
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
40
|
exports.registerCameraHandlers = void 0;
|
|
41
|
+
const Camera = __importStar(require("../modules"));
|
|
8
42
|
/**
|
|
9
43
|
* 카메라 브릿지 핸들러를 등록합니다
|
|
10
44
|
* @param config 브릿지 설정
|
|
11
45
|
*/
|
|
12
46
|
const registerCameraHandlers = (config) => {
|
|
13
|
-
const { bridge, platform,
|
|
47
|
+
const { bridge, platform, logger = console } = config;
|
|
14
48
|
// Android와 iOS만 지원
|
|
15
49
|
if (platform.OS !== 'android' && platform.OS !== 'ios') {
|
|
16
50
|
logger.log('[Bridge] Camera handlers skipped (Android/iOS only)');
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera Module (Cross-Platform)
|
|
3
|
+
* 카메라 권한 및 촬영 기능 제공
|
|
4
|
+
* Supports: Android, iOS
|
|
5
|
+
*/
|
|
6
|
+
export interface CameraPermissionStatus {
|
|
7
|
+
/** 권한 승인 여부 */
|
|
8
|
+
granted: boolean;
|
|
9
|
+
/** 권한 상태 */
|
|
10
|
+
status: string;
|
|
11
|
+
/** 카메라 권한 */
|
|
12
|
+
cameraGranted?: boolean;
|
|
13
|
+
/** 마이크 권한 */
|
|
14
|
+
micGranted?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface CameraRecordingOptions {
|
|
17
|
+
/** 카메라 방향 (front/back) */
|
|
18
|
+
facing?: 'front' | 'back';
|
|
19
|
+
/** 프레임레이트 (1-30, 기본값: 10) */
|
|
20
|
+
fps?: number;
|
|
21
|
+
/** JPEG 압축 품질 (1-100, 기본값: 30) */
|
|
22
|
+
quality?: number;
|
|
23
|
+
/** 최대 가로 해상도 (px) */
|
|
24
|
+
maxWidth?: number;
|
|
25
|
+
/** 최대 세로 해상도 (px) */
|
|
26
|
+
maxHeight?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface RecordingResult {
|
|
29
|
+
/** 성공 여부 */
|
|
30
|
+
success: boolean;
|
|
31
|
+
/** 스트리밍 여부 */
|
|
32
|
+
isStreaming?: boolean;
|
|
33
|
+
/** 오류 메시지 */
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CameraStatus {
|
|
37
|
+
/** 스트리밍 여부 */
|
|
38
|
+
isStreaming: boolean;
|
|
39
|
+
/** 카메라 방향 */
|
|
40
|
+
facing: string;
|
|
41
|
+
/** 카메라 사용 가능 여부 */
|
|
42
|
+
hasCamera: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface CrashLog {
|
|
45
|
+
/** 파일명 */
|
|
46
|
+
name: string;
|
|
47
|
+
/** 파일 경로 */
|
|
48
|
+
path: string;
|
|
49
|
+
/** 파일 크기 (bytes) */
|
|
50
|
+
size: number;
|
|
51
|
+
/** 생성 날짜 (timestamp) */
|
|
52
|
+
date: number;
|
|
53
|
+
}
|
|
54
|
+
export interface DebugLogResult {
|
|
55
|
+
/** 성공 여부 */
|
|
56
|
+
success: boolean;
|
|
57
|
+
/** 로그 내용 */
|
|
58
|
+
content?: string;
|
|
59
|
+
/** 파일 경로 */
|
|
60
|
+
path?: string;
|
|
61
|
+
/** 파일 크기 */
|
|
62
|
+
size?: number;
|
|
63
|
+
/** 파일 존재 여부 */
|
|
64
|
+
exists?: boolean;
|
|
65
|
+
/** 오류 메시지 */
|
|
66
|
+
error?: string;
|
|
67
|
+
/** 메시지 */
|
|
68
|
+
message?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface CrashLogsResult {
|
|
71
|
+
/** 성공 여부 */
|
|
72
|
+
success: boolean;
|
|
73
|
+
/** 크래시 로그 목록 */
|
|
74
|
+
logs?: CrashLog[];
|
|
75
|
+
/** 로그 개수 */
|
|
76
|
+
count?: number;
|
|
77
|
+
/** 오류 메시지 */
|
|
78
|
+
error?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface PhotoResult {
|
|
81
|
+
/** 성공 여부 */
|
|
82
|
+
success: boolean;
|
|
83
|
+
/** base64 인코딩된 이미지 */
|
|
84
|
+
base64?: string;
|
|
85
|
+
/** 이미지 너비 */
|
|
86
|
+
width?: number;
|
|
87
|
+
/** 이미지 높이 */
|
|
88
|
+
height?: number;
|
|
89
|
+
/** 사용된 카메라 방향 */
|
|
90
|
+
facing?: string;
|
|
91
|
+
/** 오류 메시지 */
|
|
92
|
+
error?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 카메라 권한 확인
|
|
96
|
+
* @returns 카메라 권한 상태
|
|
97
|
+
*/
|
|
98
|
+
export declare function checkCameraPermission(): Promise<CameraPermissionStatus>;
|
|
99
|
+
/**
|
|
100
|
+
* 카메라 권한 요청
|
|
101
|
+
* @returns 권한 요청 결과
|
|
102
|
+
*/
|
|
103
|
+
export declare function requestCameraPermission(): Promise<CameraPermissionStatus>;
|
|
104
|
+
/**
|
|
105
|
+
* 사진 촬영 (1프레임 캡처)
|
|
106
|
+
* @param facing 카메라 방향 (front/back, 기본값: back)
|
|
107
|
+
* @returns 촬영 결과 및 base64 이미지
|
|
108
|
+
*/
|
|
109
|
+
export declare function takePhoto(facing?: 'front' | 'back'): Promise<PhotoResult>;
|
|
110
|
+
/**
|
|
111
|
+
* 카메라 스트리밍 시작
|
|
112
|
+
* @param options 카메라 옵션
|
|
113
|
+
* @returns 시작 결과
|
|
114
|
+
*/
|
|
115
|
+
export declare function startCamera(options?: CameraRecordingOptions): Promise<RecordingResult>;
|
|
116
|
+
/**
|
|
117
|
+
* 비디오 녹화 중지
|
|
118
|
+
* @returns 녹화 중지 결과
|
|
119
|
+
*/
|
|
120
|
+
export declare function stopCamera(): Promise<RecordingResult>;
|
|
121
|
+
/**
|
|
122
|
+
* 카메라 상태 확인
|
|
123
|
+
* @returns 현재 카메라 상태
|
|
124
|
+
*/
|
|
125
|
+
export declare function getCameraStatus(): Promise<CameraStatus>;
|
|
126
|
+
/**
|
|
127
|
+
* 크래시 로그 목록 가져오기
|
|
128
|
+
* @returns 크래시 로그 목록
|
|
129
|
+
*/
|
|
130
|
+
export declare function getCrashLogs(): Promise<CrashLogsResult>;
|
|
131
|
+
/**
|
|
132
|
+
* 크래시 로그 공유하기 (카카오톡, 이메일 등)
|
|
133
|
+
* @param filePath 공유할 로그 파일 경로
|
|
134
|
+
* @returns 공유 성공 여부
|
|
135
|
+
*/
|
|
136
|
+
export declare function shareCrashLog(filePath: string): Promise<{
|
|
137
|
+
success: boolean;
|
|
138
|
+
error?: string;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* 모든 크래시 로그 삭제
|
|
142
|
+
* @returns 삭제 성공 여부 및 삭제된 파일 수
|
|
143
|
+
*/
|
|
144
|
+
export declare function clearCrashLogs(): Promise<{
|
|
145
|
+
success: boolean;
|
|
146
|
+
deleted?: number;
|
|
147
|
+
error?: string;
|
|
148
|
+
}>;
|
|
149
|
+
/**
|
|
150
|
+
* 디버그 로그 가져오기
|
|
151
|
+
* @returns 디버그 로그 내용
|
|
152
|
+
*/
|
|
153
|
+
export declare function getDebugLog(): Promise<DebugLogResult>;
|
|
154
|
+
/**
|
|
155
|
+
* 디버그 로그 공유하기
|
|
156
|
+
* @returns 공유 성공 여부
|
|
157
|
+
*/
|
|
158
|
+
export declare function shareDebugLog(): Promise<{
|
|
159
|
+
success: boolean;
|
|
160
|
+
error?: string;
|
|
161
|
+
}>;
|
|
162
|
+
/**
|
|
163
|
+
* 디버그 로그 삭제
|
|
164
|
+
* @returns 삭제 성공 여부
|
|
165
|
+
*/
|
|
166
|
+
export declare function clearDebugLog(): Promise<{
|
|
167
|
+
success: boolean;
|
|
168
|
+
error?: string;
|
|
169
|
+
message?: string;
|
|
170
|
+
}>;
|
|
171
|
+
/**
|
|
172
|
+
* Add listener for camera events (Expo module style)
|
|
173
|
+
* @param eventName Event name to listen to (e.g., 'onCameraFrame')
|
|
174
|
+
* @param listener Callback function to handle the event
|
|
175
|
+
* @returns Subscription object with remove() method
|
|
176
|
+
*/
|
|
177
|
+
export declare function addListener(eventName: string, listener: (event: any) => void): {
|
|
178
|
+
remove: () => void;
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Camera Module (Cross-Platform)
|
|
4
|
+
* 카메라 권한 및 촬영 기능 제공
|
|
5
|
+
* Supports: Android, iOS
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.checkCameraPermission = checkCameraPermission;
|
|
9
|
+
exports.requestCameraPermission = requestCameraPermission;
|
|
10
|
+
exports.takePhoto = takePhoto;
|
|
11
|
+
exports.startCamera = startCamera;
|
|
12
|
+
exports.stopCamera = stopCamera;
|
|
13
|
+
exports.getCameraStatus = getCameraStatus;
|
|
14
|
+
exports.getCrashLogs = getCrashLogs;
|
|
15
|
+
exports.shareCrashLog = shareCrashLog;
|
|
16
|
+
exports.clearCrashLogs = clearCrashLogs;
|
|
17
|
+
exports.getDebugLog = getDebugLog;
|
|
18
|
+
exports.shareDebugLog = shareDebugLog;
|
|
19
|
+
exports.clearDebugLog = clearDebugLog;
|
|
20
|
+
exports.addListener = addListener;
|
|
21
|
+
const expo_modules_core_1 = require("expo-modules-core");
|
|
22
|
+
const react_native_1 = require("react-native");
|
|
23
|
+
// Lazy 모듈 로드 (크래시 방지)
|
|
24
|
+
let CameraModule = null;
|
|
25
|
+
function getCameraModule() {
|
|
26
|
+
if (react_native_1.Platform.OS !== 'android' && react_native_1.Platform.OS !== 'ios') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (CameraModule === null) {
|
|
30
|
+
try {
|
|
31
|
+
CameraModule = (0, expo_modules_core_1.requireNativeModule)('CustomCamera');
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error('[CustomCamera] Failed to load native module:', error);
|
|
35
|
+
CameraModule = undefined; // 재시도 방지
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return CameraModule === undefined ? null : CameraModule;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 카메라 권한 확인
|
|
43
|
+
* @returns 카메라 권한 상태
|
|
44
|
+
*/
|
|
45
|
+
async function checkCameraPermission() {
|
|
46
|
+
const module = getCameraModule();
|
|
47
|
+
if (!module) {
|
|
48
|
+
return { granted: false, status: 'unavailable' };
|
|
49
|
+
}
|
|
50
|
+
return await module.checkCameraPermission();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 카메라 권한 요청
|
|
54
|
+
* @returns 권한 요청 결과
|
|
55
|
+
*/
|
|
56
|
+
async function requestCameraPermission() {
|
|
57
|
+
const module = getCameraModule();
|
|
58
|
+
if (!module) {
|
|
59
|
+
return { granted: false, status: 'unavailable' };
|
|
60
|
+
}
|
|
61
|
+
return await module.requestCameraPermission();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 사진 촬영 (1프레임 캡처)
|
|
65
|
+
* @param facing 카메라 방향 (front/back, 기본값: back)
|
|
66
|
+
* @returns 촬영 결과 및 base64 이미지
|
|
67
|
+
*/
|
|
68
|
+
async function takePhoto(facing) {
|
|
69
|
+
const module = getCameraModule();
|
|
70
|
+
if (!module) {
|
|
71
|
+
return { success: false, error: 'Camera module not available' };
|
|
72
|
+
}
|
|
73
|
+
return await module.takePhoto(facing || 'back');
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 카메라 스트리밍 시작
|
|
77
|
+
* @param options 카메라 옵션
|
|
78
|
+
* @returns 시작 결과
|
|
79
|
+
*/
|
|
80
|
+
async function startCamera(options) {
|
|
81
|
+
const module = getCameraModule();
|
|
82
|
+
if (!module) {
|
|
83
|
+
return { success: false, error: 'Camera module not available' };
|
|
84
|
+
}
|
|
85
|
+
// 파라미터 정규화 (호환성 유지)
|
|
86
|
+
const params = {
|
|
87
|
+
facing: options?.facing || 'back',
|
|
88
|
+
fps: options?.fps,
|
|
89
|
+
quality: options?.quality,
|
|
90
|
+
maxWidth: options?.maxWidth,
|
|
91
|
+
maxHeight: options?.maxHeight,
|
|
92
|
+
};
|
|
93
|
+
return await module.startCamera(params);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 비디오 녹화 중지
|
|
97
|
+
* @returns 녹화 중지 결과
|
|
98
|
+
*/
|
|
99
|
+
async function stopCamera() {
|
|
100
|
+
const module = getCameraModule();
|
|
101
|
+
if (!module) {
|
|
102
|
+
return { success: false, error: 'Camera module not available' };
|
|
103
|
+
}
|
|
104
|
+
return await module.stopCamera();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 카메라 상태 확인
|
|
108
|
+
* @returns 현재 카메라 상태
|
|
109
|
+
*/
|
|
110
|
+
async function getCameraStatus() {
|
|
111
|
+
const module = getCameraModule();
|
|
112
|
+
if (!module) {
|
|
113
|
+
return {
|
|
114
|
+
isStreaming: false,
|
|
115
|
+
facing: 'back',
|
|
116
|
+
hasCamera: false
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return await module.getCameraStatus();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 크래시 로그 목록 가져오기
|
|
123
|
+
* @returns 크래시 로그 목록
|
|
124
|
+
*/
|
|
125
|
+
async function getCrashLogs() {
|
|
126
|
+
const module = getCameraModule();
|
|
127
|
+
if (!module) {
|
|
128
|
+
return { success: false, error: 'Camera module not available' };
|
|
129
|
+
}
|
|
130
|
+
return await module.getCrashLogs();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 크래시 로그 공유하기 (카카오톡, 이메일 등)
|
|
134
|
+
* @param filePath 공유할 로그 파일 경로
|
|
135
|
+
* @returns 공유 성공 여부
|
|
136
|
+
*/
|
|
137
|
+
async function shareCrashLog(filePath) {
|
|
138
|
+
const module = getCameraModule();
|
|
139
|
+
if (!module) {
|
|
140
|
+
return { success: false, error: 'Camera module not available' };
|
|
141
|
+
}
|
|
142
|
+
return await module.shareCrashLog(filePath);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 모든 크래시 로그 삭제
|
|
146
|
+
* @returns 삭제 성공 여부 및 삭제된 파일 수
|
|
147
|
+
*/
|
|
148
|
+
async function clearCrashLogs() {
|
|
149
|
+
const module = getCameraModule();
|
|
150
|
+
if (!module) {
|
|
151
|
+
return { success: false, error: 'Camera module not available' };
|
|
152
|
+
}
|
|
153
|
+
return await module.clearCrashLogs();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 디버그 로그 가져오기
|
|
157
|
+
* @returns 디버그 로그 내용
|
|
158
|
+
*/
|
|
159
|
+
async function getDebugLog() {
|
|
160
|
+
const module = getCameraModule();
|
|
161
|
+
if (!module) {
|
|
162
|
+
return { success: false, error: 'Camera module not available' };
|
|
163
|
+
}
|
|
164
|
+
return await module.getDebugLog();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 디버그 로그 공유하기
|
|
168
|
+
* @returns 공유 성공 여부
|
|
169
|
+
*/
|
|
170
|
+
async function shareDebugLog() {
|
|
171
|
+
const module = getCameraModule();
|
|
172
|
+
if (!module) {
|
|
173
|
+
return { success: false, error: 'Camera module not available' };
|
|
174
|
+
}
|
|
175
|
+
return await module.shareDebugLog();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 디버그 로그 삭제
|
|
179
|
+
* @returns 삭제 성공 여부
|
|
180
|
+
*/
|
|
181
|
+
async function clearDebugLog() {
|
|
182
|
+
const module = getCameraModule();
|
|
183
|
+
if (!module) {
|
|
184
|
+
return { success: false, error: 'Camera module not available' };
|
|
185
|
+
}
|
|
186
|
+
return await module.clearDebugLog();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Add listener for camera events (Expo module style)
|
|
190
|
+
* @param eventName Event name to listen to (e.g., 'onCameraFrame')
|
|
191
|
+
* @param listener Callback function to handle the event
|
|
192
|
+
* @returns Subscription object with remove() method
|
|
193
|
+
*/
|
|
194
|
+
function addListener(eventName, listener) {
|
|
195
|
+
const module = getCameraModule();
|
|
196
|
+
if (!module || !module.addListener) {
|
|
197
|
+
console.error('[CustomCamera] addListener not available');
|
|
198
|
+
return { remove: () => { } };
|
|
199
|
+
}
|
|
200
|
+
return module.addListener(eventName, listener);
|
|
201
|
+
}
|