1

I'm attempting to record an audio file on the web using angular / typescript. I am able to successfully record the audio and listen to it with the audio player. I am attempting to take that audio and send it to a C# ASP.NET Web API post. I've tried converting it to formdata to pass as a file, but that gives me an unsupported media type.

This is the code I use for recording the audio:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { bufferToWave } from './audio-helper'
import { RESTAPIService } from './restapiservice.service';

@Injectable({
  providedIn: 'root'
})

export class AudioRecordingService {
  private chunks: any[] = [];
  private mediaRecorder: any;
  private audioContext: AudioContext = new AudioContext();
  private audioBlobSubject = new Subject<Blob>();
  private stream: any;


  private mediaConstraints = {
    audio: true
  };

  audioBlob$ = this.audioBlobSubject.asObservable();

  constructor(private service: RESTAPIService) {
  }

  async startRecording() {
    if (this.audioContext.state === 'suspended') {
      await this.audioContext.resume();
    }

    this.stream = await navigator.mediaDevices.getUserMedia(this.mediaConstraints);
    this.mediaRecorder = new MediaRecorder(this.stream);
    this.mediaRecorder.audioChannels = 1;
    this.mediaRecorder.ondataavailable = (event: any) => {
        this.chunks.push(event.data);
    };
    this.mediaRecorder.start();
  }

  async stopRecording() {

    if (this.mediaRecorder) {
      let mimeType = this.mediaRecorder.mimeType;

        this.mediaRecorder.onstop = async () => {
            const audioData = await new Blob(this.chunks).arrayBuffer();
            const audioBuffer = await this.audioContext.decodeAudioData(audioData);
            const wavBlob = bufferToWave(audioBuffer, audioBuffer.length);
            this.audioBlobSubject.next(wavBlob);

            let audioBlob = new Blob(this.chunks, { type: mimeType });

            await this.service.postAudio(audioBlob).subscribe(data => {
            });    

            this.chunks = [];
        };

        this.mediaRecorder.stop();

        if (this.stream) {
            this.stream.getAudioTracks().forEach(function(track: { stop: () => void; }) {
                track.stop();
            });

            this.stream.getVideoTracks().forEach(function(track: { stop: () => void; }) {
                track.stop();
            });
        }
    }
  }
}

Code to send audio data to the C# ASP.NET Web API:

  constructor(private http: HttpClient) { }

  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'multipart/form-data'
    })
  };

  postAudio(blob: Blob)
  {
    const formData = new FormData();
    formData.append("Test", blob);


    let url = "https://localhost:7048/api/Transcribe/UploadAudio";
    return this.http.post(url, formData);
  }

C# ASP.NET Web API code:

[HttpPost("UploadAudio")]
public async Task<IActionResult> UploadAudio(IFormFile formFile)
{
    return Ok("");
}

I've tried the code above and I was expecting the file to be transferred to the c# api. Instead I get either a 415 or 400 error.

1
  • 1. When using FormData, you don't need to set Content-Type manually. The browser will automatically set the correct Content-Type including the boundary - that's probably causing the HTTP415 error. 2. Make sure you've got CORS setup for everything to start off with services.AddCors(options => { options.AddPolicy("AllowAllOrigins" Commented Jul 15, 2024 at 5:27

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.