-
-
Save jdnichollsc/9d450ee36d9d75b201c01549f8f36fd7 to your computer and use it in GitHub Desktop.
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; | |
} | |
} | |
} | |
} |
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)) |
Awesome, thanks for letting me know! <3
I am trying to implement the same solution but it's not working for, can you please help me out, below i am adding the code with the issue, Please let me, i will be grateful. Thank you
this.audioFile = await this.file.createFile(this.filePath, this.record.FileName, true);
this.mediaObject = this.media.create(this.audioFile.nativeURL);
async uploadFile() {
await delayTimer(200);
this.audioFile.file(async file => {
const blob = await this.getBlobFromFile(file) // fIle return of IFile not File
})
}
getBlobFromFile(file: File): Promise<Blob> {
return new Promise((resolve, reject) => {
let fileReader = this.utils.getFileReader();
fileReader.onloadend = function() {
console.log(this.result);
var blob = new Blob([this.result], { type: file.type })
resolve(blob);
};
fileReader.onerror = function(err) {
reject(err);
};
fileReader.readAsArrayBuffer(file); //(parameter) file: FileArgument of type 'File' is not assignable to parameter of type 'Blob'.
Type 'File' is missing the following properties from type 'Blob': size, type, arrayBuffer, slice, and 2
});
}
getFileReader(): FileReader {
const fileReader = new FileReader();
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
return zoneOriginalInstance || fileReader;
}
That error is clear, type is wrong :)
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!
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();
}
}
I solved managed to solve the errors and am now able to upload the audio file to firebase Storage.
Appreciate the help very much!
Now the code looks like:
Because I am using capacitor I needed to fetch the FileReader instance in a different way. So
this.mainService.getFileReader()
translates to:Thanks again! :)