1

I've been trying for a long time to get the audio time (seconds) of a mp3 file upload in my Angular 2 App.

I've tried some different approaches (one of them), but i haven't been able to get it to work yet.

I was hoping to do it the Angular way - without calling document.querySelector(...) or window.URL for the URL.createObjectURL().

If i try with @ViewChild('file') and a function on the field called with (change) and call it with $event and the ViewChild:

<input #file type="file" class="form-control-file" (change)="setFileField($event, file)">

None of them contains the duration data, but i am able to get the file data through the event:

let files: FileList = event.target.files;
let file: File = files[0];

// File data from the event
lastModified: 1526819830000
lastModifiedDate: Sun May 20 2018 14:37:10 GMT+0200 (CEST) {}
name: "Det lægende samspil mellem det ydre og det indre mørke_pt1 - med Anders Laugesen.mp3"
size: 18792325
type: "audio/mp3"

If i wait and try to loop through the FormGroup data on the (ngSubmit), the data isn't there as well.

I've read about an event called (loadedmetadata) but i can't get it to function in my app.

What should i do to get the duration of this file upload in an Angular 2 app, if i want to do it the Angular way?

1 Answers1

3

The best solution i found was to combine angulars (change) and (canplaythrough).

<input type="file" class="form-control-file" (change)="setFileField($event)">
<audio #dom_audio (canplaythrough)="setDuration($event)" id="audio"></audio>

The setFile gets the file from the files list, creates the object url and sets it in on the audio html tag:

setFile(event) {
  let files: FileList = event.target.files;
  if (files.length > 0) {
    this.file = files[0];
  }
  if(this.file.name.match(/\.(avi|mp3|mp4|mpeg|ogg)$/i)){
    let obUrl = URL.createObjectURL(this.file);
    this.dom_audio.nativeElement.setAttribute('src', obUrl);
  }
}

Then, when the audio file can be played through - the .duration property is ready to be saved:

setDuration(load_event): void {
  this.duration = Math.round(load_event.currentTarget.duration);
}

And then i pass this.duration to the post params on ngSubmit and saves it in the database.

Note: Remember to validate the presence of duration. You don't want the user to save the file without this attribute.

I hope it can help somebody.