@independo/capacitor-voice-recorder 8.0.2-dev.1 → 8.1.0-dev.2

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.
Files changed (81) hide show
  1. package/README.md +130 -32
  2. package/android/build.gradle +44 -1
  3. package/android/src/main/java/app/independo/capacitorvoicerecorder/VoiceRecorder.java +146 -0
  4. package/android/src/main/java/app/independo/capacitorvoicerecorder/adapters/PermissionChecker.java +8 -0
  5. package/android/src/main/java/app/independo/capacitorvoicerecorder/adapters/RecordDataMapper.java +32 -0
  6. package/android/src/main/java/app/independo/capacitorvoicerecorder/adapters/RecorderAdapter.java +39 -0
  7. package/android/src/main/java/app/independo/capacitorvoicerecorder/adapters/RecorderPlatform.java +25 -0
  8. package/android/src/main/java/app/independo/capacitorvoicerecorder/core/CurrentRecordingStatus.java +9 -0
  9. package/android/src/main/java/app/independo/capacitorvoicerecorder/core/ErrorCodes.java +19 -0
  10. package/android/src/main/java/{com/tchvu3/capacitorvoicerecorder → app/independo/capacitorvoicerecorder/core}/Messages.java +2 -1
  11. package/android/src/main/java/{com/tchvu3/capacitorvoicerecorder → app/independo/capacitorvoicerecorder/core}/RecordData.java +15 -1
  12. package/android/src/main/java/app/independo/capacitorvoicerecorder/core/RecordOptions.java +4 -0
  13. package/android/src/main/java/app/independo/capacitorvoicerecorder/core/ResponseFormat.java +18 -0
  14. package/android/src/main/java/{com/tchvu3/capacitorvoicerecorder → app/independo/capacitorvoicerecorder/core}/ResponseGenerator.java +7 -1
  15. package/android/src/main/java/app/independo/capacitorvoicerecorder/platform/CustomMediaRecorder.java +281 -0
  16. package/android/src/main/java/app/independo/capacitorvoicerecorder/platform/DefaultRecorderPlatform.java +86 -0
  17. package/android/src/main/java/app/independo/capacitorvoicerecorder/platform/NotSupportedOsVersion.java +4 -0
  18. package/android/src/main/java/app/independo/capacitorvoicerecorder/service/VoiceRecorderService.java +144 -0
  19. package/android/src/main/java/app/independo/capacitorvoicerecorder/service/VoiceRecorderServiceException.java +23 -0
  20. package/dist/docs.json +145 -5
  21. package/dist/esm/adapters/VoiceRecorderWebAdapter.d.ts +23 -0
  22. package/dist/esm/adapters/VoiceRecorderWebAdapter.js +41 -0
  23. package/dist/esm/adapters/VoiceRecorderWebAdapter.js.map +1 -0
  24. package/dist/esm/core/error-codes.d.ts +4 -0
  25. package/dist/esm/core/error-codes.js +21 -0
  26. package/dist/esm/core/error-codes.js.map +1 -0
  27. package/dist/esm/core/recording-contract.d.ts +3 -0
  28. package/dist/esm/core/recording-contract.js +15 -0
  29. package/dist/esm/core/recording-contract.js.map +1 -0
  30. package/dist/esm/core/response-format.d.ts +8 -0
  31. package/dist/esm/core/response-format.js +17 -0
  32. package/dist/esm/core/response-format.js.map +1 -0
  33. package/dist/esm/definitions.d.ts +36 -3
  34. package/dist/esm/definitions.js.map +1 -1
  35. package/dist/esm/platform/web/VoiceRecorderImpl.d.ts +45 -0
  36. package/dist/esm/{VoiceRecorderImpl.js → platform/web/VoiceRecorderImpl.js} +20 -2
  37. package/dist/esm/platform/web/VoiceRecorderImpl.js.map +1 -0
  38. package/dist/esm/platform/web/get-blob-duration.js.map +1 -0
  39. package/dist/esm/{predefined-web-responses.d.ts → platform/web/predefined-web-responses.d.ts} +12 -1
  40. package/dist/esm/{predefined-web-responses.js → platform/web/predefined-web-responses.js} +11 -0
  41. package/dist/esm/platform/web/predefined-web-responses.js.map +1 -0
  42. package/dist/esm/service/VoiceRecorderService.d.ts +47 -0
  43. package/dist/esm/service/VoiceRecorderService.js +60 -0
  44. package/dist/esm/service/VoiceRecorderService.js.map +1 -0
  45. package/dist/esm/web.d.ts +12 -1
  46. package/dist/esm/web.js +26 -12
  47. package/dist/esm/web.js.map +1 -1
  48. package/dist/plugin.cjs.js +200 -9
  49. package/dist/plugin.cjs.js.map +1 -1
  50. package/dist/plugin.js +200 -9
  51. package/dist/plugin.js.map +1 -1
  52. package/ios/Sources/VoiceRecorder/Adapters/DefaultRecorderPlatform.swift +33 -0
  53. package/ios/Sources/VoiceRecorder/Adapters/RecordDataMapper.swift +38 -0
  54. package/ios/Sources/VoiceRecorder/Adapters/RecorderAdapter.swift +24 -0
  55. package/ios/Sources/VoiceRecorder/Adapters/RecorderPlatform.swift +11 -0
  56. package/ios/Sources/VoiceRecorder/Bridge/VoiceRecorder.swift +172 -0
  57. package/ios/Sources/VoiceRecorder/{CurrentRecordingStatus.swift → Core/CurrentRecordingStatus.swift} +2 -0
  58. package/ios/Sources/VoiceRecorder/Core/ErrorCodes.swift +16 -0
  59. package/ios/Sources/VoiceRecorder/{Messages.swift → Core/Messages.swift} +2 -0
  60. package/ios/Sources/VoiceRecorder/{RecordData.swift → Core/RecordData.swift} +6 -0
  61. package/ios/Sources/VoiceRecorder/Core/RecordOptions.swift +11 -0
  62. package/ios/Sources/VoiceRecorder/Core/ResponseFormat.swift +22 -0
  63. package/ios/Sources/VoiceRecorder/{ResponseGenerator.swift → Core/ResponseGenerator.swift} +6 -0
  64. package/ios/Sources/VoiceRecorder/Platform/CustomMediaRecorder.swift +359 -0
  65. package/ios/Sources/VoiceRecorder/Service/VoiceRecorderService.swift +128 -0
  66. package/ios/Sources/VoiceRecorder/Service/VoiceRecorderServiceError.swift +14 -0
  67. package/package.json +10 -4
  68. package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/CurrentRecordingStatus.java +0 -7
  69. package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/CustomMediaRecorder.java +0 -149
  70. package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/NotSupportedOsVersion.java +0 -3
  71. package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/RecordOptions.java +0 -3
  72. package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/VoiceRecorder.java +0 -203
  73. package/dist/esm/VoiceRecorderImpl.d.ts +0 -27
  74. package/dist/esm/VoiceRecorderImpl.js.map +0 -1
  75. package/dist/esm/helper/get-blob-duration.js.map +0 -1
  76. package/dist/esm/predefined-web-responses.js.map +0 -1
  77. package/ios/Sources/VoiceRecorder/CustomMediaRecorder.swift +0 -113
  78. package/ios/Sources/VoiceRecorder/RecordOptions.swift +0 -8
  79. package/ios/Sources/VoiceRecorder/VoiceRecorder.swift +0 -147
  80. /package/dist/esm/{helper → platform/web}/get-blob-duration.d.ts +0 -0
  81. /package/dist/esm/{helper → platform/web}/get-blob-duration.js +0 -0
@@ -1,113 +0,0 @@
1
- import Foundation
2
- import AVFoundation
3
-
4
- class CustomMediaRecorder {
5
-
6
- public var options: RecordOptions?
7
- private var recordingSession: AVAudioSession!
8
- private var audioRecorder: AVAudioRecorder!
9
- private var audioFilePath: URL!
10
- private var originalRecordingSessionCategory: AVAudioSession.Category!
11
- private var status = CurrentRecordingStatus.NONE
12
-
13
- private let settings = [
14
- AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
15
- AVSampleRateKey: 44100,
16
- AVNumberOfChannelsKey: 1,
17
- AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
18
- ]
19
-
20
- private func getDirectoryToSaveAudioFile() -> URL {
21
- if options?.directory != nil,
22
- let directory = getDirectory(directory: options?.directory),
23
- var outputDirURL = FileManager.default.urls(for: directory, in: .userDomainMask).first {
24
- if let subDirectory = options?.subDirectory?.trimmingCharacters(in: CharacterSet(charactersIn: "/")) {
25
- outputDirURL = outputDirURL.appendingPathComponent(subDirectory, isDirectory: true)
26
-
27
- do {
28
- if !FileManager.default.fileExists(atPath: outputDirURL.path) {
29
- try FileManager.default.createDirectory(at: outputDirURL, withIntermediateDirectories: true)
30
- }
31
- } catch {
32
- print("Error creating directory: \(error)")
33
- }
34
- }
35
-
36
- return outputDirURL
37
- }
38
-
39
- return URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
40
- }
41
-
42
- public func startRecording(recordOptions: RecordOptions?) -> Bool {
43
- do {
44
- options = recordOptions
45
- recordingSession = AVAudioSession.sharedInstance()
46
- originalRecordingSessionCategory = recordingSession.category
47
- try recordingSession.setCategory(AVAudioSession.Category.playAndRecord)
48
- try recordingSession.setActive(true)
49
- audioFilePath = getDirectoryToSaveAudioFile().appendingPathComponent("recording-\(Int(Date().timeIntervalSince1970 * 1000)).aac")
50
- audioRecorder = try AVAudioRecorder(url: audioFilePath, settings: settings)
51
- audioRecorder.record()
52
- status = CurrentRecordingStatus.RECORDING
53
- return true
54
- } catch {
55
- return false
56
- }
57
- }
58
-
59
- public func stopRecording() {
60
- do {
61
- audioRecorder.stop()
62
- try recordingSession.setActive(false)
63
- try recordingSession.setCategory(originalRecordingSessionCategory)
64
- originalRecordingSessionCategory = nil
65
- audioRecorder = nil
66
- recordingSession = nil
67
- status = CurrentRecordingStatus.NONE
68
- } catch {}
69
- }
70
-
71
- public func getOutputFile() -> URL {
72
- return audioFilePath
73
- }
74
-
75
- public func getDirectory(directory: String?) -> FileManager.SearchPathDirectory? {
76
- if let directory = directory {
77
- switch directory {
78
- case "CACHE":
79
- return .cachesDirectory
80
- case "LIBRARY":
81
- return .libraryDirectory
82
- default:
83
- return .documentDirectory
84
- }
85
- }
86
- return nil
87
- }
88
-
89
- public func pauseRecording() -> Bool {
90
- if(status == CurrentRecordingStatus.RECORDING) {
91
- audioRecorder.pause()
92
- status = CurrentRecordingStatus.PAUSED
93
- return true
94
- } else {
95
- return false
96
- }
97
- }
98
-
99
- public func resumeRecording() -> Bool {
100
- if(status == CurrentRecordingStatus.PAUSED) {
101
- audioRecorder.record()
102
- status = CurrentRecordingStatus.RECORDING
103
- return true
104
- } else {
105
- return false
106
- }
107
- }
108
-
109
- public func getCurrentStatus() -> CurrentRecordingStatus {
110
- return status
111
- }
112
-
113
- }
@@ -1,8 +0,0 @@
1
- import Foundation
2
-
3
- struct RecordOptions {
4
-
5
- public let directory: String?
6
- public let subDirectory: String?
7
-
8
- }
@@ -1,147 +0,0 @@
1
- import Foundation
2
- import AVFoundation
3
- import Capacitor
4
-
5
- @objc(VoiceRecorder)
6
- public class VoiceRecorder: CAPPlugin, CAPBridgedPlugin {
7
- public let identifier = "VoiceRecorder"
8
- public let jsName = "VoiceRecorder"
9
- public let pluginMethods: [CAPPluginMethod] = [
10
- CAPPluginMethod(name: "canDeviceVoiceRecord", returnType: CAPPluginReturnPromise),
11
- CAPPluginMethod(name: "requestAudioRecordingPermission", returnType: CAPPluginReturnPromise),
12
- CAPPluginMethod(name: "hasAudioRecordingPermission", returnType: CAPPluginReturnPromise),
13
- CAPPluginMethod(name: "startRecording", returnType: CAPPluginReturnPromise),
14
- CAPPluginMethod(name: "stopRecording", returnType: CAPPluginReturnPromise),
15
- CAPPluginMethod(name: "pauseRecording", returnType: CAPPluginReturnPromise),
16
- CAPPluginMethod(name: "resumeRecording", returnType: CAPPluginReturnPromise),
17
- CAPPluginMethod(name: "getCurrentStatus", returnType: CAPPluginReturnPromise),
18
- ]
19
-
20
- private var customMediaRecorder: CustomMediaRecorder? = nil
21
-
22
- @objc func canDeviceVoiceRecord(_ call: CAPPluginCall) {
23
- call.resolve(ResponseGenerator.successResponse())
24
- }
25
-
26
- @objc func requestAudioRecordingPermission(_ call: CAPPluginCall) {
27
- AVAudioSession.sharedInstance().requestRecordPermission { granted in
28
- if granted {
29
- call.resolve(ResponseGenerator.successResponse())
30
- } else {
31
- call.resolve(ResponseGenerator.failResponse())
32
- }
33
- }
34
- }
35
-
36
- @objc func hasAudioRecordingPermission(_ call: CAPPluginCall) {
37
- call.resolve(ResponseGenerator.fromBoolean(doesUserGaveAudioRecordingPermission()))
38
- }
39
-
40
- @objc func startRecording(_ call: CAPPluginCall) {
41
- if(!doesUserGaveAudioRecordingPermission()) {
42
- call.reject(Messages.MISSING_PERMISSION)
43
- return
44
- }
45
-
46
- if(customMediaRecorder != nil) {
47
- call.reject(Messages.ALREADY_RECORDING)
48
- return
49
- }
50
-
51
- customMediaRecorder = CustomMediaRecorder()
52
- if(customMediaRecorder == nil) {
53
- call.reject(Messages.CANNOT_RECORD_ON_THIS_PHONE)
54
- return
55
- }
56
-
57
- let directory: String? = call.getString("directory")
58
- let subDirectory: String? = call.getString("subDirectory")
59
- let recordOptions = RecordOptions(directory: directory, subDirectory: subDirectory)
60
- let successfullyStartedRecording = customMediaRecorder!.startRecording(recordOptions: recordOptions)
61
- if successfullyStartedRecording == false {
62
- call.reject(Messages.CANNOT_RECORD_ON_THIS_PHONE)
63
- } else {
64
- call.resolve(ResponseGenerator.successResponse())
65
- }
66
- }
67
-
68
- @objc func stopRecording(_ call: CAPPluginCall) {
69
- if(customMediaRecorder == nil) {
70
- call.reject(Messages.RECORDING_HAS_NOT_STARTED)
71
- return
72
- }
73
-
74
- customMediaRecorder?.stopRecording()
75
-
76
- let audioFileUrl = customMediaRecorder?.getOutputFile()
77
- if(audioFileUrl == nil) {
78
- customMediaRecorder = nil
79
- call.reject(Messages.FAILED_TO_FETCH_RECORDING)
80
- return
81
- }
82
-
83
- let sendDataAsBase64 = customMediaRecorder?.options?.directory == nil
84
- let recordData = RecordData(
85
- recordDataBase64: sendDataAsBase64 ? readFileAsBase64(audioFileUrl) : nil,
86
- mimeType: "audio/aac",
87
- msDuration: getMsDurationOfAudioFile(audioFileUrl),
88
- uri: sendDataAsBase64 ? nil : audioFileUrl!.path
89
- )
90
- customMediaRecorder = nil
91
- if (sendDataAsBase64 && recordData.recordDataBase64 == nil) || recordData.msDuration < 0 {
92
- call.reject(Messages.EMPTY_RECORDING)
93
- } else {
94
- call.resolve(ResponseGenerator.dataResponse(recordData.toDictionary()))
95
- }
96
- }
97
-
98
- @objc func pauseRecording(_ call: CAPPluginCall) {
99
- if(customMediaRecorder == nil) {
100
- call.reject(Messages.RECORDING_HAS_NOT_STARTED)
101
- } else {
102
- call.resolve(ResponseGenerator.fromBoolean(customMediaRecorder?.pauseRecording() ?? false))
103
- }
104
- }
105
-
106
- @objc func resumeRecording(_ call: CAPPluginCall) {
107
- if(customMediaRecorder == nil) {
108
- call.reject(Messages.RECORDING_HAS_NOT_STARTED)
109
- } else {
110
- call.resolve(ResponseGenerator.fromBoolean(customMediaRecorder?.resumeRecording() ?? false))
111
- }
112
- }
113
-
114
- @objc func getCurrentStatus(_ call: CAPPluginCall) {
115
- if(customMediaRecorder == nil) {
116
- call.resolve(ResponseGenerator.statusResponse(CurrentRecordingStatus.NONE))
117
- } else {
118
- call.resolve(ResponseGenerator.statusResponse(customMediaRecorder?.getCurrentStatus() ?? CurrentRecordingStatus.NONE))
119
- }
120
- }
121
-
122
- func doesUserGaveAudioRecordingPermission() -> Bool {
123
- return AVAudioSession.sharedInstance().recordPermission == AVAudioSession.RecordPermission.granted
124
- }
125
-
126
- func readFileAsBase64(_ filePath: URL?) -> String? {
127
- if(filePath == nil) {
128
- return nil
129
- }
130
-
131
- do {
132
- let fileData = try Data.init(contentsOf: filePath!)
133
- let fileStream = fileData.base64EncodedString(options: NSData.Base64EncodingOptions.init(rawValue: 0))
134
- return fileStream
135
- } catch {}
136
-
137
- return nil
138
- }
139
-
140
- func getMsDurationOfAudioFile(_ filePath: URL?) -> Int {
141
- if filePath == nil {
142
- return -1
143
- }
144
- return Int(CMTimeGetSeconds(AVURLAsset(url: filePath!).duration) * 1000)
145
- }
146
-
147
- }