@independo/capacitor-voice-recorder 5.0.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.
- package/CapacitorVoiceRecorder.podspec +17 -0
- package/README.md +232 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/CurrentRecordingStatus.java +7 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/CustomMediaRecorder.java +107 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/Messages.java +14 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/NotSupportedOsVersion.java +3 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/RecordData.java +50 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/ResponseGenerator.java +37 -0
- package/android/src/main/java/com/tchvu3/capacitorvoicerecorder/VoiceRecorder.java +184 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +246 -0
- package/dist/esm/VoiceRecorderImpl.d.ts +19 -0
- package/dist/esm/VoiceRecorderImpl.js +176 -0
- package/dist/esm/VoiceRecorderImpl.js.map +1 -0
- package/dist/esm/definitions.d.ts +124 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/predefined-web-responses.d.ts +12 -0
- package/dist/esm/predefined-web-responses.js +12 -0
- package/dist/esm/predefined-web-responses.js.map +1 -0
- package/dist/esm/web.d.ts +13 -0
- package/dist/esm/web.js +33 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +232 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +234 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/CurrentRecordingStatus.swift +9 -0
- package/ios/Plugin/CustomMediaRecorder.swift +79 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Messages.swift +15 -0
- package/ios/Plugin/RecordData.swift +17 -0
- package/ios/Plugin/ResponseGenerator.swift +28 -0
- package/ios/Plugin/VoiceRecorder.swift +130 -0
- package/ios/Plugin/VoiceRecorderPlugin.h +10 -0
- package/ios/Plugin/VoiceRecorderPlugin.m +15 -0
- package/package.json +97 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a Base64 encoded string.
|
|
3
|
+
*/
|
|
4
|
+
export declare type Base64String = string;
|
|
5
|
+
/**
|
|
6
|
+
* Interface representing the data of a recording.
|
|
7
|
+
*/
|
|
8
|
+
export interface RecordingData {
|
|
9
|
+
/**
|
|
10
|
+
* The value containing the recording details.
|
|
11
|
+
*/
|
|
12
|
+
value: {
|
|
13
|
+
/**
|
|
14
|
+
* The recorded data as a Base64 encoded string.
|
|
15
|
+
*/
|
|
16
|
+
recordDataBase64: Base64String;
|
|
17
|
+
/**
|
|
18
|
+
* The duration of the recording in milliseconds.
|
|
19
|
+
*/
|
|
20
|
+
msDuration: number;
|
|
21
|
+
/**
|
|
22
|
+
* The MIME type of the recorded file.
|
|
23
|
+
*/
|
|
24
|
+
mimeType: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Interface representing a generic response with a boolean value.
|
|
29
|
+
*/
|
|
30
|
+
export interface GenericResponse {
|
|
31
|
+
/**
|
|
32
|
+
* The result of the operation as a boolean value.
|
|
33
|
+
*/
|
|
34
|
+
value: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Interface representing the current status of the voice recorder.
|
|
38
|
+
*/
|
|
39
|
+
export interface CurrentRecordingStatus {
|
|
40
|
+
/**
|
|
41
|
+
* The current status of the recorder, which can be one of the following values: 'RECORDING', 'PAUSED', 'NONE'.
|
|
42
|
+
*/
|
|
43
|
+
status: 'RECORDING' | 'PAUSED' | 'NONE';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Interface for the VoiceRecorderPlugin which provides methods to record audio.
|
|
47
|
+
*/
|
|
48
|
+
export interface VoiceRecorderPlugin {
|
|
49
|
+
/**
|
|
50
|
+
* Checks if the current device can record audio.
|
|
51
|
+
* On mobile, this function will always resolve to `{ value: true }`.
|
|
52
|
+
* In a browser, it will resolve to `{ value: true }` or `{ value: false }` based on the browser's ability to record.
|
|
53
|
+
* This method does not take into account the permission status, only if the browser itself is capable of recording at all.
|
|
54
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
55
|
+
* @throws Error with code "COULD_NOT_QUERY_PERMISSION_STATUS" if the device cannot query the permission status.
|
|
56
|
+
*/
|
|
57
|
+
canDeviceVoiceRecord(): Promise<GenericResponse>;
|
|
58
|
+
/**
|
|
59
|
+
* Requests audio recording permission from the user.
|
|
60
|
+
* If the permission has already been provided, the promise will resolve with `{ value: true }`.
|
|
61
|
+
* Otherwise, the promise will resolve to `{ value: true }` or `{ value: false }` based on the user's response.
|
|
62
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
63
|
+
* @throws Error if the permission request fails.
|
|
64
|
+
*/
|
|
65
|
+
requestAudioRecordingPermission(): Promise<GenericResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Checks if audio recording permission has been granted.
|
|
68
|
+
* Will resolve to `{ value: true }` or `{ value: false }` based on the status of the permission.
|
|
69
|
+
* The web implementation of this plugin uses the Permissions API, which is not widespread.
|
|
70
|
+
* If the status of the permission cannot be checked, the promise will reject with `COULD_NOT_QUERY_PERMISSION_STATUS`.
|
|
71
|
+
* In that case, use `requestAudioRecordingPermission` or `startRecording` and capture any exception that is thrown.
|
|
72
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
73
|
+
* @throws Error with code "COULD_NOT_QUERY_PERMISSION_STATUS" if the device cannot query the permission status.
|
|
74
|
+
*/
|
|
75
|
+
hasAudioRecordingPermission(): Promise<GenericResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Starts audio recording.
|
|
78
|
+
* On success, the promise will resolve to { value: true }.
|
|
79
|
+
* On error, the promise will reject with one of the following error codes:
|
|
80
|
+
* "MISSING_PERMISSION", "ALREADY_RECORDING", "MICROPHONE_BEING_USED", "DEVICE_CANNOT_VOICE_RECORD", or "FAILED_TO_RECORD".
|
|
81
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
82
|
+
* @throws Error with one of the specified error codes if the recording cannot be started.
|
|
83
|
+
*/
|
|
84
|
+
startRecording(): Promise<GenericResponse>;
|
|
85
|
+
/**
|
|
86
|
+
* Stops audio recording.
|
|
87
|
+
* Will stop the recording that has been previously started.
|
|
88
|
+
* If the function `startRecording` has not been called beforehand, the promise will reject with `RECORDING_HAS_NOT_STARTED`.
|
|
89
|
+
* If the recording has been stopped immediately after it has been started, the promise will reject with `EMPTY_RECORDING`.
|
|
90
|
+
* In a case of unknown error, the promise will reject with `FAILED_TO_FETCH_RECORDING`.
|
|
91
|
+
* In case of success, the promise resolves to RecordingData containing the recording in base-64, the duration of the recording in milliseconds, and the MIME type.
|
|
92
|
+
* @returns A promise that resolves to RecordingData.
|
|
93
|
+
* @throws Error with one of the specified error codes if the recording cannot be stopped.
|
|
94
|
+
*/
|
|
95
|
+
stopRecording(): Promise<RecordingData>;
|
|
96
|
+
/**
|
|
97
|
+
* Pauses the ongoing audio recording.
|
|
98
|
+
* If the recording has not started yet, the promise will reject with an error code `RECORDING_HAS_NOT_STARTED`.
|
|
99
|
+
* On success, the promise will resolve to { value: true } if the pause was successful or { value: false } if the recording is already paused.
|
|
100
|
+
* On certain mobile OS versions, this function is not supported and will reject with `NOT_SUPPORTED_OS_VERSION`.
|
|
101
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
102
|
+
* @throws Error with one of the specified error codes if the recording cannot be paused.
|
|
103
|
+
*/
|
|
104
|
+
pauseRecording(): Promise<GenericResponse>;
|
|
105
|
+
/**
|
|
106
|
+
* Resumes a paused audio recording.
|
|
107
|
+
* If the recording has not started yet, the promise will reject with an error code `RECORDING_HAS_NOT_STARTED`.
|
|
108
|
+
* On success, the promise will resolve to { value: true } if the resume was successful or { value: false } if the recording is already running.
|
|
109
|
+
* On certain mobile OS versions, this function is not supported and will reject with `NOT_SUPPORTED_OS_VERSION`.
|
|
110
|
+
* @returns A promise that resolves to a GenericResponse.
|
|
111
|
+
* @throws Error with one of the specified error codes if the recording cannot be resumed.
|
|
112
|
+
*/
|
|
113
|
+
resumeRecording(): Promise<GenericResponse>;
|
|
114
|
+
/**
|
|
115
|
+
* Gets the current status of the voice recorder.
|
|
116
|
+
* Will resolve with one of the following values:
|
|
117
|
+
* `{ status: "NONE" }` if the plugin is idle and waiting to start a new recording.
|
|
118
|
+
* `{ status: "RECORDING" }` if the plugin is in the middle of recording.
|
|
119
|
+
* `{ status: "PAUSED" }` if the recording is paused.
|
|
120
|
+
* @returns A promise that resolves to a CurrentRecordingStatus.
|
|
121
|
+
* @throws Error if the status cannot be fetched.
|
|
122
|
+
*/
|
|
123
|
+
getCurrentStatus(): Promise<CurrentRecordingStatus>;
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Represents a Base64 encoded string.\n */\nexport type Base64String = string;\n\n/**\n * Interface representing the data of a recording.\n */\nexport interface RecordingData {\n /**\n * The value containing the recording details.\n */\n value: {\n /**\n * The recorded data as a Base64 encoded string.\n */\n recordDataBase64: Base64String;\n /**\n * The duration of the recording in milliseconds.\n */\n msDuration: number;\n /**\n * The MIME type of the recorded file.\n */\n mimeType: string;\n };\n}\n\n/**\n * Interface representing a generic response with a boolean value.\n */\nexport interface GenericResponse {\n /**\n * The result of the operation as a boolean value.\n */\n value: boolean;\n}\n\n/**\n * Interface representing the current status of the voice recorder.\n */\nexport interface CurrentRecordingStatus {\n /**\n * The current status of the recorder, which can be one of the following values: 'RECORDING', 'PAUSED', 'NONE'.\n */\n status: 'RECORDING' | 'PAUSED' | 'NONE';\n}\n\n/**\n * Interface for the VoiceRecorderPlugin which provides methods to record audio.\n */\nexport interface VoiceRecorderPlugin {\n /**\n * Checks if the current device can record audio.\n * On mobile, this function will always resolve to `{ value: true }`.\n * In a browser, it will resolve to `{ value: true }` or `{ value: false }` based on the browser's ability to record.\n * This method does not take into account the permission status, only if the browser itself is capable of recording at all.\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error with code \"COULD_NOT_QUERY_PERMISSION_STATUS\" if the device cannot query the permission status.\n */\n canDeviceVoiceRecord(): Promise<GenericResponse>;\n\n /**\n * Requests audio recording permission from the user.\n * If the permission has already been provided, the promise will resolve with `{ value: true }`.\n * Otherwise, the promise will resolve to `{ value: true }` or `{ value: false }` based on the user's response.\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error if the permission request fails.\n */\n requestAudioRecordingPermission(): Promise<GenericResponse>;\n\n /**\n * Checks if audio recording permission has been granted.\n * Will resolve to `{ value: true }` or `{ value: false }` based on the status of the permission.\n * The web implementation of this plugin uses the Permissions API, which is not widespread.\n * If the status of the permission cannot be checked, the promise will reject with `COULD_NOT_QUERY_PERMISSION_STATUS`.\n * In that case, use `requestAudioRecordingPermission` or `startRecording` and capture any exception that is thrown.\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error with code \"COULD_NOT_QUERY_PERMISSION_STATUS\" if the device cannot query the permission status.\n */\n hasAudioRecordingPermission(): Promise<GenericResponse>;\n\n /**\n * Starts audio recording.\n * On success, the promise will resolve to { value: true }.\n * On error, the promise will reject with one of the following error codes:\n * \"MISSING_PERMISSION\", \"ALREADY_RECORDING\", \"MICROPHONE_BEING_USED\", \"DEVICE_CANNOT_VOICE_RECORD\", or \"FAILED_TO_RECORD\".\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error with one of the specified error codes if the recording cannot be started.\n */\n startRecording(): Promise<GenericResponse>;\n\n /**\n * Stops audio recording.\n * Will stop the recording that has been previously started.\n * If the function `startRecording` has not been called beforehand, the promise will reject with `RECORDING_HAS_NOT_STARTED`.\n * If the recording has been stopped immediately after it has been started, the promise will reject with `EMPTY_RECORDING`.\n * In a case of unknown error, the promise will reject with `FAILED_TO_FETCH_RECORDING`.\n * In case of success, the promise resolves to RecordingData containing the recording in base-64, the duration of the recording in milliseconds, and the MIME type.\n * @returns A promise that resolves to RecordingData.\n * @throws Error with one of the specified error codes if the recording cannot be stopped.\n */\n stopRecording(): Promise<RecordingData>;\n\n /**\n * Pauses the ongoing audio recording.\n * If the recording has not started yet, the promise will reject with an error code `RECORDING_HAS_NOT_STARTED`.\n * On success, the promise will resolve to { value: true } if the pause was successful or { value: false } if the recording is already paused.\n * On certain mobile OS versions, this function is not supported and will reject with `NOT_SUPPORTED_OS_VERSION`.\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error with one of the specified error codes if the recording cannot be paused.\n */\n pauseRecording(): Promise<GenericResponse>;\n\n /**\n * Resumes a paused audio recording.\n * If the recording has not started yet, the promise will reject with an error code `RECORDING_HAS_NOT_STARTED`.\n * On success, the promise will resolve to { value: true } if the resume was successful or { value: false } if the recording is already running.\n * On certain mobile OS versions, this function is not supported and will reject with `NOT_SUPPORTED_OS_VERSION`.\n * @returns A promise that resolves to a GenericResponse.\n * @throws Error with one of the specified error codes if the recording cannot be resumed.\n */\n resumeRecording(): Promise<GenericResponse>;\n\n /**\n * Gets the current status of the voice recorder.\n * Will resolve with one of the following values:\n * `{ status: \"NONE\" }` if the plugin is idle and waiting to start a new recording.\n * `{ status: \"RECORDING\" }` if the plugin is in the middle of recording.\n * `{ status: \"PAUSED\" }` if the recording is paused.\n * @returns A promise that resolves to a CurrentRecordingStatus.\n * @throws Error if the status cannot be fetched.\n */\n getCurrentStatus(): Promise<CurrentRecordingStatus>;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { registerPlugin } from '@capacitor/core';
|
|
2
|
+
const VoiceRecorder = registerPlugin('VoiceRecorder', {
|
|
3
|
+
web: () => import('./web').then((m) => new m.VoiceRecorderWeb()),
|
|
4
|
+
});
|
|
5
|
+
export * from './definitions';
|
|
6
|
+
export { VoiceRecorder };
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,aAAa,GAAG,cAAc,CAAsB,eAAe,EAAE;IACzE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;CACjE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { VoiceRecorderPlugin } from './definitions';\n\nconst VoiceRecorder = registerPlugin<VoiceRecorderPlugin>('VoiceRecorder', {\n web: () => import('./web').then((m) => new m.VoiceRecorderWeb()),\n});\n\nexport * from './definitions';\nexport { VoiceRecorder };\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GenericResponse } from './definitions';
|
|
2
|
+
export declare const successResponse: () => GenericResponse;
|
|
3
|
+
export declare const failureResponse: () => GenericResponse;
|
|
4
|
+
export declare const missingPermissionError: () => Error;
|
|
5
|
+
export declare const alreadyRecordingError: () => Error;
|
|
6
|
+
export declare const microphoneBeingUsedError: () => Error;
|
|
7
|
+
export declare const deviceCannotVoiceRecordError: () => Error;
|
|
8
|
+
export declare const failedToRecordError: () => Error;
|
|
9
|
+
export declare const emptyRecordingError: () => Error;
|
|
10
|
+
export declare const recordingHasNotStartedError: () => Error;
|
|
11
|
+
export declare const failedToFetchRecordingError: () => Error;
|
|
12
|
+
export declare const couldNotQueryPermissionStatusError: () => Error;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const successResponse = () => ({ value: true });
|
|
2
|
+
export const failureResponse = () => ({ value: false });
|
|
3
|
+
export const missingPermissionError = () => new Error('MISSING_PERMISSION');
|
|
4
|
+
export const alreadyRecordingError = () => new Error('ALREADY_RECORDING');
|
|
5
|
+
export const microphoneBeingUsedError = () => new Error('MICROPHONE_BEING_USED');
|
|
6
|
+
export const deviceCannotVoiceRecordError = () => new Error('DEVICE_CANNOT_VOICE_RECORD');
|
|
7
|
+
export const failedToRecordError = () => new Error('FAILED_TO_RECORD');
|
|
8
|
+
export const emptyRecordingError = () => new Error('EMPTY_RECORDING');
|
|
9
|
+
export const recordingHasNotStartedError = () => new Error('RECORDING_HAS_NOT_STARTED');
|
|
10
|
+
export const failedToFetchRecordingError = () => new Error('FAILED_TO_FETCH_RECORDING');
|
|
11
|
+
export const couldNotQueryPermissionStatusError = () => new Error('COULD_NOT_QUERY_PERMISSION_STATUS');
|
|
12
|
+
//# sourceMappingURL=predefined-web-responses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predefined-web-responses.js","sourceRoot":"","sources":["../../src/predefined-web-responses.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACxE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AACxF,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;AACjG,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC/F,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,kCAAkC,GAAG,GAAU,EAAE,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC","sourcesContent":["import type { GenericResponse } from './definitions';\n\nexport const successResponse = (): GenericResponse => ({ value: true });\nexport const failureResponse = (): GenericResponse => ({ value: false });\n\nexport const missingPermissionError = (): Error => new Error('MISSING_PERMISSION');\nexport const alreadyRecordingError = (): Error => new Error('ALREADY_RECORDING');\nexport const microphoneBeingUsedError = (): Error => new Error('MICROPHONE_BEING_USED');\nexport const deviceCannotVoiceRecordError = (): Error => new Error('DEVICE_CANNOT_VOICE_RECORD');\nexport const failedToRecordError = (): Error => new Error('FAILED_TO_RECORD');\nexport const emptyRecordingError = (): Error => new Error('EMPTY_RECORDING');\n\nexport const recordingHasNotStartedError = (): Error => new Error('RECORDING_HAS_NOT_STARTED');\nexport const failedToFetchRecordingError = (): Error => new Error('FAILED_TO_FETCH_RECORDING');\n\nexport const couldNotQueryPermissionStatusError = (): Error => new Error('COULD_NOT_QUERY_PERMISSION_STATUS');\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import type { CurrentRecordingStatus, GenericResponse, RecordingData, VoiceRecorderPlugin } from './definitions';
|
|
3
|
+
export declare class VoiceRecorderWeb extends WebPlugin implements VoiceRecorderPlugin {
|
|
4
|
+
private voiceRecorderInstance;
|
|
5
|
+
canDeviceVoiceRecord(): Promise<GenericResponse>;
|
|
6
|
+
hasAudioRecordingPermission(): Promise<GenericResponse>;
|
|
7
|
+
requestAudioRecordingPermission(): Promise<GenericResponse>;
|
|
8
|
+
startRecording(): Promise<GenericResponse>;
|
|
9
|
+
stopRecording(): Promise<RecordingData>;
|
|
10
|
+
pauseRecording(): Promise<GenericResponse>;
|
|
11
|
+
resumeRecording(): Promise<GenericResponse>;
|
|
12
|
+
getCurrentStatus(): Promise<CurrentRecordingStatus>;
|
|
13
|
+
}
|
package/dist/esm/web.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import { VoiceRecorderImpl } from './VoiceRecorderImpl';
|
|
3
|
+
export class VoiceRecorderWeb extends WebPlugin {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.voiceRecorderInstance = new VoiceRecorderImpl();
|
|
7
|
+
}
|
|
8
|
+
canDeviceVoiceRecord() {
|
|
9
|
+
return VoiceRecorderImpl.canDeviceVoiceRecord();
|
|
10
|
+
}
|
|
11
|
+
hasAudioRecordingPermission() {
|
|
12
|
+
return VoiceRecorderImpl.hasAudioRecordingPermission();
|
|
13
|
+
}
|
|
14
|
+
requestAudioRecordingPermission() {
|
|
15
|
+
return VoiceRecorderImpl.requestAudioRecordingPermission();
|
|
16
|
+
}
|
|
17
|
+
startRecording() {
|
|
18
|
+
return this.voiceRecorderInstance.startRecording();
|
|
19
|
+
}
|
|
20
|
+
stopRecording() {
|
|
21
|
+
return this.voiceRecorderInstance.stopRecording();
|
|
22
|
+
}
|
|
23
|
+
pauseRecording() {
|
|
24
|
+
return this.voiceRecorderInstance.pauseRecording();
|
|
25
|
+
}
|
|
26
|
+
resumeRecording() {
|
|
27
|
+
return this.voiceRecorderInstance.resumeRecording();
|
|
28
|
+
}
|
|
29
|
+
getCurrentStatus() {
|
|
30
|
+
return this.voiceRecorderInstance.getCurrentStatus();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAA/C;;QACU,0BAAqB,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAiC1D,CAAC;IA/BQ,oBAAoB;QACzB,OAAO,iBAAiB,CAAC,oBAAoB,EAAE,CAAC;IAClD,CAAC;IAEM,2BAA2B;QAChC,OAAO,iBAAiB,CAAC,2BAA2B,EAAE,CAAC;IACzD,CAAC;IAEM,+BAA+B;QACpC,OAAO,iBAAiB,CAAC,+BAA+B,EAAE,CAAC;IAC7D,CAAC;IAEM,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;IACrD,CAAC;IAEM,aAAa;QAClB,OAAO,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;IACpD,CAAC;IAEM,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;IACrD,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC;IACtD,CAAC;IAEM,gBAAgB;QACrB,OAAO,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;IACvD,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport { VoiceRecorderImpl } from './VoiceRecorderImpl';\nimport type { CurrentRecordingStatus, GenericResponse, RecordingData, VoiceRecorderPlugin } from './definitions';\n\nexport class VoiceRecorderWeb extends WebPlugin implements VoiceRecorderPlugin {\n private voiceRecorderInstance = new VoiceRecorderImpl();\n\n public canDeviceVoiceRecord(): Promise<GenericResponse> {\n return VoiceRecorderImpl.canDeviceVoiceRecord();\n }\n\n public hasAudioRecordingPermission(): Promise<GenericResponse> {\n return VoiceRecorderImpl.hasAudioRecordingPermission();\n }\n\n public requestAudioRecordingPermission(): Promise<GenericResponse> {\n return VoiceRecorderImpl.requestAudioRecordingPermission();\n }\n\n public startRecording(): Promise<GenericResponse> {\n return this.voiceRecorderInstance.startRecording();\n }\n\n public stopRecording(): Promise<RecordingData> {\n return this.voiceRecorderInstance.stopRecording();\n }\n\n public pauseRecording(): Promise<GenericResponse> {\n return this.voiceRecorderInstance.pauseRecording();\n }\n\n public resumeRecording(): Promise<GenericResponse> {\n return this.voiceRecorderInstance.resumeRecording();\n }\n\n public getCurrentStatus(): Promise<CurrentRecordingStatus> {\n return this.voiceRecorderInstance.getCurrentStatus();\n }\n}\n"]}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@capacitor/core');
|
|
4
|
+
var getBlobDuration = require('get-blob-duration');
|
|
5
|
+
|
|
6
|
+
const VoiceRecorder = core.registerPlugin('VoiceRecorder', {
|
|
7
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.VoiceRecorderWeb()),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const successResponse = () => ({ value: true });
|
|
11
|
+
const failureResponse = () => ({ value: false });
|
|
12
|
+
const missingPermissionError = () => new Error('MISSING_PERMISSION');
|
|
13
|
+
const alreadyRecordingError = () => new Error('ALREADY_RECORDING');
|
|
14
|
+
const deviceCannotVoiceRecordError = () => new Error('DEVICE_CANNOT_VOICE_RECORD');
|
|
15
|
+
const failedToRecordError = () => new Error('FAILED_TO_RECORD');
|
|
16
|
+
const emptyRecordingError = () => new Error('EMPTY_RECORDING');
|
|
17
|
+
const recordingHasNotStartedError = () => new Error('RECORDING_HAS_NOT_STARTED');
|
|
18
|
+
const failedToFetchRecordingError = () => new Error('FAILED_TO_FETCH_RECORDING');
|
|
19
|
+
const couldNotQueryPermissionStatusError = () => new Error('COULD_NOT_QUERY_PERMISSION_STATUS');
|
|
20
|
+
|
|
21
|
+
// these mime types will be checked one by one in order until one of them is found to be supported by the current browser
|
|
22
|
+
const possibleMimeTypes = ['audio/aac', 'audio/webm;codecs=opus', 'audio/mp4', 'audio/webm', 'audio/ogg;codecs=opus'];
|
|
23
|
+
const neverResolvingPromise = () => new Promise(() => undefined);
|
|
24
|
+
class VoiceRecorderImpl {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.mediaRecorder = null;
|
|
27
|
+
this.chunks = [];
|
|
28
|
+
this.pendingResult = neverResolvingPromise();
|
|
29
|
+
}
|
|
30
|
+
static async canDeviceVoiceRecord() {
|
|
31
|
+
var _a;
|
|
32
|
+
if (((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) == null || VoiceRecorderImpl.getSupportedMimeType() == null) {
|
|
33
|
+
return failureResponse();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return successResponse();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async startRecording() {
|
|
40
|
+
if (this.mediaRecorder != null) {
|
|
41
|
+
throw alreadyRecordingError();
|
|
42
|
+
}
|
|
43
|
+
const deviceCanRecord = await VoiceRecorderImpl.canDeviceVoiceRecord();
|
|
44
|
+
if (!deviceCanRecord.value) {
|
|
45
|
+
throw deviceCannotVoiceRecordError();
|
|
46
|
+
}
|
|
47
|
+
const havingPermission = await VoiceRecorderImpl.hasAudioRecordingPermission().catch(() => successResponse());
|
|
48
|
+
if (!havingPermission.value) {
|
|
49
|
+
throw missingPermissionError();
|
|
50
|
+
}
|
|
51
|
+
return navigator.mediaDevices
|
|
52
|
+
.getUserMedia({ audio: true })
|
|
53
|
+
.then(this.onSuccessfullyStartedRecording.bind(this))
|
|
54
|
+
.catch(this.onFailedToStartRecording.bind(this));
|
|
55
|
+
}
|
|
56
|
+
async stopRecording() {
|
|
57
|
+
if (this.mediaRecorder == null) {
|
|
58
|
+
throw recordingHasNotStartedError();
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
this.mediaRecorder.stop();
|
|
62
|
+
this.mediaRecorder.stream.getTracks().forEach((track) => track.stop());
|
|
63
|
+
return this.pendingResult;
|
|
64
|
+
}
|
|
65
|
+
catch (ignore) {
|
|
66
|
+
throw failedToFetchRecordingError();
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
this.prepareInstanceForNextOperation();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
static async hasAudioRecordingPermission() {
|
|
73
|
+
return navigator.permissions
|
|
74
|
+
.query({ name: 'microphone' })
|
|
75
|
+
.then((result) => ({ value: result.state === 'granted' }))
|
|
76
|
+
.catch(() => {
|
|
77
|
+
throw couldNotQueryPermissionStatusError();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static async requestAudioRecordingPermission() {
|
|
81
|
+
const havingPermission = await VoiceRecorderImpl.hasAudioRecordingPermission().catch(() => failureResponse());
|
|
82
|
+
if (havingPermission.value) {
|
|
83
|
+
return successResponse();
|
|
84
|
+
}
|
|
85
|
+
return navigator.mediaDevices
|
|
86
|
+
.getUserMedia({ audio: true })
|
|
87
|
+
.then(() => successResponse())
|
|
88
|
+
.catch(() => failureResponse());
|
|
89
|
+
}
|
|
90
|
+
pauseRecording() {
|
|
91
|
+
if (this.mediaRecorder == null) {
|
|
92
|
+
throw recordingHasNotStartedError();
|
|
93
|
+
}
|
|
94
|
+
else if (this.mediaRecorder.state === 'recording') {
|
|
95
|
+
this.mediaRecorder.pause();
|
|
96
|
+
return Promise.resolve(successResponse());
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return Promise.resolve(failureResponse());
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
resumeRecording() {
|
|
103
|
+
if (this.mediaRecorder == null) {
|
|
104
|
+
throw recordingHasNotStartedError();
|
|
105
|
+
}
|
|
106
|
+
else if (this.mediaRecorder.state === 'paused') {
|
|
107
|
+
this.mediaRecorder.resume();
|
|
108
|
+
return Promise.resolve(successResponse());
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
return Promise.resolve(failureResponse());
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
getCurrentStatus() {
|
|
115
|
+
if (this.mediaRecorder == null) {
|
|
116
|
+
return Promise.resolve({ status: 'NONE' });
|
|
117
|
+
}
|
|
118
|
+
else if (this.mediaRecorder.state === 'recording') {
|
|
119
|
+
return Promise.resolve({ status: 'RECORDING' });
|
|
120
|
+
}
|
|
121
|
+
else if (this.mediaRecorder.state === 'paused') {
|
|
122
|
+
return Promise.resolve({ status: 'PAUSED' });
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return Promise.resolve({ status: 'NONE' });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
static getSupportedMimeType() {
|
|
129
|
+
if ((MediaRecorder === null || MediaRecorder === void 0 ? void 0 : MediaRecorder.isTypeSupported) == null)
|
|
130
|
+
return null;
|
|
131
|
+
const foundSupportedType = possibleMimeTypes.find((type) => MediaRecorder.isTypeSupported(type));
|
|
132
|
+
return foundSupportedType !== null && foundSupportedType !== void 0 ? foundSupportedType : null;
|
|
133
|
+
}
|
|
134
|
+
onSuccessfullyStartedRecording(stream) {
|
|
135
|
+
this.pendingResult = new Promise((resolve, reject) => {
|
|
136
|
+
this.mediaRecorder = new MediaRecorder(stream);
|
|
137
|
+
this.mediaRecorder.onerror = () => {
|
|
138
|
+
this.prepareInstanceForNextOperation();
|
|
139
|
+
reject(failedToRecordError());
|
|
140
|
+
};
|
|
141
|
+
this.mediaRecorder.onstop = async () => {
|
|
142
|
+
const mimeType = VoiceRecorderImpl.getSupportedMimeType();
|
|
143
|
+
if (mimeType == null) {
|
|
144
|
+
this.prepareInstanceForNextOperation();
|
|
145
|
+
reject(failedToFetchRecordingError());
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const blobVoiceRecording = new Blob(this.chunks, { type: mimeType });
|
|
149
|
+
if (blobVoiceRecording.size <= 0) {
|
|
150
|
+
this.prepareInstanceForNextOperation();
|
|
151
|
+
reject(emptyRecordingError());
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const recordDataBase64 = await VoiceRecorderImpl.blobToBase64(blobVoiceRecording);
|
|
155
|
+
const recordingDuration = await getBlobDuration(blobVoiceRecording);
|
|
156
|
+
this.prepareInstanceForNextOperation();
|
|
157
|
+
resolve({ value: { recordDataBase64, mimeType, msDuration: recordingDuration * 1000 } });
|
|
158
|
+
};
|
|
159
|
+
this.mediaRecorder.ondataavailable = (event) => this.chunks.push(event.data);
|
|
160
|
+
this.mediaRecorder.start();
|
|
161
|
+
});
|
|
162
|
+
return successResponse();
|
|
163
|
+
}
|
|
164
|
+
onFailedToStartRecording() {
|
|
165
|
+
this.prepareInstanceForNextOperation();
|
|
166
|
+
throw failedToRecordError();
|
|
167
|
+
}
|
|
168
|
+
static blobToBase64(blob) {
|
|
169
|
+
return new Promise((resolve) => {
|
|
170
|
+
const reader = new FileReader();
|
|
171
|
+
reader.onloadend = () => {
|
|
172
|
+
const recordingResult = String(reader.result);
|
|
173
|
+
const splitResult = recordingResult.split('base64,');
|
|
174
|
+
const toResolve = splitResult.length > 1 ? splitResult[1] : recordingResult;
|
|
175
|
+
resolve(toResolve.trim());
|
|
176
|
+
};
|
|
177
|
+
reader.readAsDataURL(blob);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
prepareInstanceForNextOperation() {
|
|
181
|
+
if (this.mediaRecorder != null && this.mediaRecorder.state === 'recording') {
|
|
182
|
+
try {
|
|
183
|
+
this.mediaRecorder.stop();
|
|
184
|
+
}
|
|
185
|
+
catch (ignore) {
|
|
186
|
+
console.warn('Failed to stop recording during cleanup');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
this.pendingResult = neverResolvingPromise();
|
|
190
|
+
this.mediaRecorder = null;
|
|
191
|
+
this.chunks = [];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
class VoiceRecorderWeb extends core.WebPlugin {
|
|
196
|
+
constructor() {
|
|
197
|
+
super(...arguments);
|
|
198
|
+
this.voiceRecorderInstance = new VoiceRecorderImpl();
|
|
199
|
+
}
|
|
200
|
+
canDeviceVoiceRecord() {
|
|
201
|
+
return VoiceRecorderImpl.canDeviceVoiceRecord();
|
|
202
|
+
}
|
|
203
|
+
hasAudioRecordingPermission() {
|
|
204
|
+
return VoiceRecorderImpl.hasAudioRecordingPermission();
|
|
205
|
+
}
|
|
206
|
+
requestAudioRecordingPermission() {
|
|
207
|
+
return VoiceRecorderImpl.requestAudioRecordingPermission();
|
|
208
|
+
}
|
|
209
|
+
startRecording() {
|
|
210
|
+
return this.voiceRecorderInstance.startRecording();
|
|
211
|
+
}
|
|
212
|
+
stopRecording() {
|
|
213
|
+
return this.voiceRecorderInstance.stopRecording();
|
|
214
|
+
}
|
|
215
|
+
pauseRecording() {
|
|
216
|
+
return this.voiceRecorderInstance.pauseRecording();
|
|
217
|
+
}
|
|
218
|
+
resumeRecording() {
|
|
219
|
+
return this.voiceRecorderInstance.resumeRecording();
|
|
220
|
+
}
|
|
221
|
+
getCurrentStatus() {
|
|
222
|
+
return this.voiceRecorderInstance.getCurrentStatus();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
227
|
+
__proto__: null,
|
|
228
|
+
VoiceRecorderWeb: VoiceRecorderWeb
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
exports.VoiceRecorder = VoiceRecorder;
|
|
232
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/predefined-web-responses.js","esm/VoiceRecorderImpl.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst VoiceRecorder = registerPlugin('VoiceRecorder', {\n web: () => import('./web').then((m) => new m.VoiceRecorderWeb()),\n});\nexport * from './definitions';\nexport { VoiceRecorder };\n//# sourceMappingURL=index.js.map","export const successResponse = () => ({ value: true });\nexport const failureResponse = () => ({ value: false });\nexport const missingPermissionError = () => new Error('MISSING_PERMISSION');\nexport const alreadyRecordingError = () => new Error('ALREADY_RECORDING');\nexport const microphoneBeingUsedError = () => new Error('MICROPHONE_BEING_USED');\nexport const deviceCannotVoiceRecordError = () => new Error('DEVICE_CANNOT_VOICE_RECORD');\nexport const failedToRecordError = () => new Error('FAILED_TO_RECORD');\nexport const emptyRecordingError = () => new Error('EMPTY_RECORDING');\nexport const recordingHasNotStartedError = () => new Error('RECORDING_HAS_NOT_STARTED');\nexport const failedToFetchRecordingError = () => new Error('FAILED_TO_FETCH_RECORDING');\nexport const couldNotQueryPermissionStatusError = () => new Error('COULD_NOT_QUERY_PERMISSION_STATUS');\n//# sourceMappingURL=predefined-web-responses.js.map","import getBlobDuration from 'get-blob-duration';\nimport { alreadyRecordingError, couldNotQueryPermissionStatusError, deviceCannotVoiceRecordError, emptyRecordingError, failedToFetchRecordingError, failedToRecordError, failureResponse, missingPermissionError, recordingHasNotStartedError, successResponse, } from './predefined-web-responses';\n// these mime types will be checked one by one in order until one of them is found to be supported by the current browser\nconst possibleMimeTypes = ['audio/aac', 'audio/webm;codecs=opus', 'audio/mp4', 'audio/webm', 'audio/ogg;codecs=opus'];\nconst neverResolvingPromise = () => new Promise(() => undefined);\nexport class VoiceRecorderImpl {\n constructor() {\n this.mediaRecorder = null;\n this.chunks = [];\n this.pendingResult = neverResolvingPromise();\n }\n static async canDeviceVoiceRecord() {\n var _a;\n if (((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) == null || VoiceRecorderImpl.getSupportedMimeType() == null) {\n return failureResponse();\n }\n else {\n return successResponse();\n }\n }\n async startRecording() {\n if (this.mediaRecorder != null) {\n throw alreadyRecordingError();\n }\n const deviceCanRecord = await VoiceRecorderImpl.canDeviceVoiceRecord();\n if (!deviceCanRecord.value) {\n throw deviceCannotVoiceRecordError();\n }\n const havingPermission = await VoiceRecorderImpl.hasAudioRecordingPermission().catch(() => successResponse());\n if (!havingPermission.value) {\n throw missingPermissionError();\n }\n return navigator.mediaDevices\n .getUserMedia({ audio: true })\n .then(this.onSuccessfullyStartedRecording.bind(this))\n .catch(this.onFailedToStartRecording.bind(this));\n }\n async stopRecording() {\n if (this.mediaRecorder == null) {\n throw recordingHasNotStartedError();\n }\n try {\n this.mediaRecorder.stop();\n this.mediaRecorder.stream.getTracks().forEach((track) => track.stop());\n return this.pendingResult;\n }\n catch (ignore) {\n throw failedToFetchRecordingError();\n }\n finally {\n this.prepareInstanceForNextOperation();\n }\n }\n static async hasAudioRecordingPermission() {\n return navigator.permissions\n .query({ name: 'microphone' })\n .then((result) => ({ value: result.state === 'granted' }))\n .catch(() => {\n throw couldNotQueryPermissionStatusError();\n });\n }\n static async requestAudioRecordingPermission() {\n const havingPermission = await VoiceRecorderImpl.hasAudioRecordingPermission().catch(() => failureResponse());\n if (havingPermission.value) {\n return successResponse();\n }\n return navigator.mediaDevices\n .getUserMedia({ audio: true })\n .then(() => successResponse())\n .catch(() => failureResponse());\n }\n pauseRecording() {\n if (this.mediaRecorder == null) {\n throw recordingHasNotStartedError();\n }\n else if (this.mediaRecorder.state === 'recording') {\n this.mediaRecorder.pause();\n return Promise.resolve(successResponse());\n }\n else {\n return Promise.resolve(failureResponse());\n }\n }\n resumeRecording() {\n if (this.mediaRecorder == null) {\n throw recordingHasNotStartedError();\n }\n else if (this.mediaRecorder.state === 'paused') {\n this.mediaRecorder.resume();\n return Promise.resolve(successResponse());\n }\n else {\n return Promise.resolve(failureResponse());\n }\n }\n getCurrentStatus() {\n if (this.mediaRecorder == null) {\n return Promise.resolve({ status: 'NONE' });\n }\n else if (this.mediaRecorder.state === 'recording') {\n return Promise.resolve({ status: 'RECORDING' });\n }\n else if (this.mediaRecorder.state === 'paused') {\n return Promise.resolve({ status: 'PAUSED' });\n }\n else {\n return Promise.resolve({ status: 'NONE' });\n }\n }\n static getSupportedMimeType() {\n if ((MediaRecorder === null || MediaRecorder === void 0 ? void 0 : MediaRecorder.isTypeSupported) == null)\n return null;\n const foundSupportedType = possibleMimeTypes.find((type) => MediaRecorder.isTypeSupported(type));\n return foundSupportedType !== null && foundSupportedType !== void 0 ? foundSupportedType : null;\n }\n onSuccessfullyStartedRecording(stream) {\n this.pendingResult = new Promise((resolve, reject) => {\n this.mediaRecorder = new MediaRecorder(stream);\n this.mediaRecorder.onerror = () => {\n this.prepareInstanceForNextOperation();\n reject(failedToRecordError());\n };\n this.mediaRecorder.onstop = async () => {\n const mimeType = VoiceRecorderImpl.getSupportedMimeType();\n if (mimeType == null) {\n this.prepareInstanceForNextOperation();\n reject(failedToFetchRecordingError());\n return;\n }\n const blobVoiceRecording = new Blob(this.chunks, { type: mimeType });\n if (blobVoiceRecording.size <= 0) {\n this.prepareInstanceForNextOperation();\n reject(emptyRecordingError());\n return;\n }\n const recordDataBase64 = await VoiceRecorderImpl.blobToBase64(blobVoiceRecording);\n const recordingDuration = await getBlobDuration(blobVoiceRecording);\n this.prepareInstanceForNextOperation();\n resolve({ value: { recordDataBase64, mimeType, msDuration: recordingDuration * 1000 } });\n };\n this.mediaRecorder.ondataavailable = (event) => this.chunks.push(event.data);\n this.mediaRecorder.start();\n });\n return successResponse();\n }\n onFailedToStartRecording() {\n this.prepareInstanceForNextOperation();\n throw failedToRecordError();\n }\n static blobToBase64(blob) {\n return new Promise((resolve) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n const recordingResult = String(reader.result);\n const splitResult = recordingResult.split('base64,');\n const toResolve = splitResult.length > 1 ? splitResult[1] : recordingResult;\n resolve(toResolve.trim());\n };\n reader.readAsDataURL(blob);\n });\n }\n prepareInstanceForNextOperation() {\n if (this.mediaRecorder != null && this.mediaRecorder.state === 'recording') {\n try {\n this.mediaRecorder.stop();\n }\n catch (ignore) {\n console.warn('Failed to stop recording during cleanup');\n }\n }\n this.pendingResult = neverResolvingPromise();\n this.mediaRecorder = null;\n this.chunks = [];\n }\n}\n//# sourceMappingURL=VoiceRecorderImpl.js.map","import { WebPlugin } from '@capacitor/core';\nimport { VoiceRecorderImpl } from './VoiceRecorderImpl';\nexport class VoiceRecorderWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.voiceRecorderInstance = new VoiceRecorderImpl();\n }\n canDeviceVoiceRecord() {\n return VoiceRecorderImpl.canDeviceVoiceRecord();\n }\n hasAudioRecordingPermission() {\n return VoiceRecorderImpl.hasAudioRecordingPermission();\n }\n requestAudioRecordingPermission() {\n return VoiceRecorderImpl.requestAudioRecordingPermission();\n }\n startRecording() {\n return this.voiceRecorderInstance.startRecording();\n }\n stopRecording() {\n return this.voiceRecorderInstance.stopRecording();\n }\n pauseRecording() {\n return this.voiceRecorderInstance.pauseRecording();\n }\n resumeRecording() {\n return this.voiceRecorderInstance.resumeRecording();\n }\n getCurrentStatus() {\n return this.voiceRecorderInstance.getCurrentStatus();\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|