Last active
July 17, 2021 05:18
-
-
Save jdnichollsc/9d450ee36d9d75b201c01549f8f36fd7 to your computer and use it in GitHub Desktop.
Record audio (Cordova/Ionic) using cordova-plugin-media and cordova-plugin-file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Media, MediaObject } from '@ionic-native/media'; | |
import { File as NativeFile, FileEntry } from '@ionic-native/file'; | |
import { delay, getBlobFromFileEntry } from './utils' | |
// Detect platform device and select extension (Cordova platform, etc) | |
// Android | |
const AUDIO_EXTENSION = '.mp3' | |
// iOS | |
const AUDIO_EXTENSION = '.m4a' | |
export class PageDemo { | |
private audioFile: FileEntry | |
private audioMedia: MediaObject | |
// private audioMediaSrc: string | |
async onStartRecording() { | |
const path = NativeFile.dataDirectory; | |
const name = `record_${(new Date()).getTime() + AUDIO_EXTENSION}`; | |
this.audioFile = await NativeFile.createFile(path, name, true); | |
// Deprecated versions | |
// this.audioMediaSrc = this.audioFile.nativeURL.replace(/^file:[\/]+/, ''); | |
// this.audioMedia = Media.create(this.audioMediaSrc); | |
this.audioMedia = Media.create(this.audioFile.nativeURL); | |
this.audioMedia.startRecord(); | |
} | |
async onStopRecording() { | |
if (this.audioFile) { | |
try { | |
this.audioMedia.stopRecord(); | |
// It requires a little delay to get media file data | |
await delay(200); | |
const blob = await getBlobFromFileEntry(this.audioFile); | |
// SAVE AUDIO HERE! | |
// uploadFile(this.audioFile.name, blob) | |
} finally { | |
this.audioFile = null; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { FileEntry } from '@ionic-native/file'; | |
export const getBlobFromFileEntry = (fileEntry: FileEntry): Promise<Blob> => { | |
return new Promise((resolve, reject) => { | |
fileEntry.file((file) => { | |
const reader = new FileReader(); | |
reader.onloadend = function(e) { | |
try { | |
const { result: buffer } = e.target | |
const blob = new Blob( | |
[new Uint8Array(buffer as any)], | |
{ type: file.type } | |
); | |
resolve(blob); | |
} catch (error) { | |
reject(error); | |
} | |
}; | |
reader.onabort = (ev) => reject(ev); | |
reader.onerror = (ev) => reject(ev); | |
reader.readAsArrayBuffer(file); | |
}, reject) | |
}) | |
} | |
export const delay = (time: number) => | |
new Promise(resolve => setTimeout(() => resolve(), time)) |
Why are you using that format? 3gp
. Do you know if that codec is supported by that platform? Did you request the permissions for recording audio?
I am not using any specific format, it seems like it is the default. This is my entire code, I didn't manually request permissions, but the dialog for recording and file access does popup.
@Injectable()
export class MediaService {
private readonly logger = new Logger(this.constructor.name);
constructor(private readonly media: Media, private readonly file: File) {}
async recordAudio(): Promise<void> {
const path = this.file.dataDirectory;
const name = 'recording.mp3';
const file = await this.file.createFile(path, name, true);
console.log('file native url', file.nativeURL);
const mediaFile: MediaObject = this.media.create(file.nativeURL);
mediaFile.startRecord();
await wait(10000);
this.logger.debug('recording stopped');
mediaFile.stopRecord();
await wait(1000);
this.logger.debug('playing started');
mediaFile.play();
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi guys, great example, thanks, but I am running into a strange problem (although I am setting the file path manualy as above):
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/tmprecording-1626497965957.3gp: open failed: EPERM (Operation not permitted)
Adding android:requestLegacyExternalStorage="true" solved the problem, but I would need to avoid that.
Any idea? Thanks!