55// Created by BAO HA on 13/12/24.
66//
77
8+ import AVFoundation
89import HXPhotoPicker
10+ import Photos
911
1012extension HybridMultipleImagePicker {
1113 func openCamera( config: NitroCameraConfig , resolved: @escaping ( ( CameraResult ) -> Void ) , rejected: @escaping ( ( Double ) -> Void ) ) throws {
14+ var captureType : CameraController . CaptureType = . all
15+
16+ // check media type
17+ switch config. mediaType {
18+ case . image:
19+ captureType = . photo
20+ case . video:
21+ captureType = . video
22+ default :
23+ break
24+ }
25+
26+ // config
1227 var cameraConfig = CameraConfiguration ( )
1328
1429 cameraConfig. videoMaximumDuration = config. videoMaximumDuration ?? 60
@@ -26,8 +41,7 @@ extension HybridMultipleImagePicker {
2641
2742 cameraConfig. languageType = setLocale ( language: config. language)
2843 cameraConfig. isSaveSystemAlbum = config. isSaveSystemAlbum ?? false
29- cameraConfig. allowLocation = config. allowLocation ?? true
30- cameraConfig. sessionPreset = . hd1920x1080
44+ cameraConfig. sessionPreset = . hd4K3840x2160
3145 cameraConfig. aspectRatio = . fullScreen
3246
3347 if let color = config. color, let focusColor = getReactColor ( Int ( color) ) {
@@ -41,9 +55,62 @@ extension HybridMultipleImagePicker {
4155 cameraConfig. position = . back
4256 }
4357
58+ func getCameraResult( _ result: CameraController . Result , _ asset: PHAsset ? ) {
59+ if let asset {
60+ Task {
61+ let photoAsset = PhotoAsset ( asset)
62+ let urlResult = try await photoAsset. urlResult ( )
63+ let path = urlResult. url. absoluteString
64+
65+ let phAsset = photoAsset. phAsset
66+ let thumbnail = phAsset? . getVideoAssetThumbnail ( from: path, in: 1 )
67+
68+ resolved ( CameraResult ( path: path, type: photoAsset. mediaType == . photo ? ResultType . image : ResultType . video, width: photoAsset. imageSize. width, height: photoAsset. imageSize. height, duration: photoAsset. videoDuration, thumbnail: thumbnail, fileName: phAsset? . fileName) )
69+ }
70+
71+ } else {
72+ switch result {
73+ case . image( let uiImage) :
74+
75+ let fileName = " IMG_ \( Int ( Date ( ) . timeIntervalSince1970) ) .jpg "
76+ let filePath = uiImage. getPath ( fileName: fileName, quality: 1.0 )
77+
78+ if let filePath {
79+ resolved ( CameraResult ( path: filePath, type: ResultType . image, width: uiImage. size. width, height: uiImage. size. height, duration: nil , thumbnail: nil , fileName: fileName) )
80+ } else {
81+ rejected ( 0 )
82+ }
83+
84+ case . video( let url) :
85+
86+ let asset = AVAsset ( url: url)
87+
88+ let thumbnail = getVideoThumbnail ( from: url. absoluteString, in: 1 )
89+
90+ var result = CameraResult ( path: url. absoluteString,
91+ type: ResultType . video,
92+ width: nil ,
93+ height: nil ,
94+ duration: asset. duration. seconds,
95+ thumbnail: thumbnail,
96+ fileName: url. lastPathComponent)
97+
98+ if let track = asset. tracks ( withMediaType: AVMediaType . video) . first {
99+ let trackSize = track. naturalSize. applying ( track. preferredTransform)
100+ let size = CGSize ( width: abs ( trackSize. width) , height: abs ( trackSize. height) )
101+
102+ result. width = Double ( size. width)
103+ result. height = Double ( size. height)
104+ }
105+
106+ resolved ( result)
107+ }
108+ }
109+ }
110+
44111 DispatchQueue . main. async {
45- Photo . capture ( cameraConfig) { result, _ , _ in
46- print ( " result: " , result )
112+ Photo . capture ( cameraConfig, type : captureType ) { result, asset , _ in
113+ getCameraResult ( result, asset )
47114 }
48115 }
49116 }
0 commit comments