locked
Recording Audio with Javascript

    Question

  • I want to record audio using javascript. I am pretty sure I want to use Windows.Media.Capture to achieve this. However, I am having trouble understanding the code there and in the examples. I listed below the code for what I want to achieve. Can someone explain how I would go about recording the audio? Thanks.

    var RecordAudio = function (src) {
    	this.src = src;
    };
    
    RecordAudio.prototype.record = function () {
    	//...
    };
    
    RecordAudio.prototype.stop = function () {
    	//...
    };
    
    var src = 'recording.mp3';
    var recorder = new RecordAudio (src);
    recorder.record();
    recorder.stop();


    • Edited by MPBerk Thursday, July 12, 2012 5:04 PM
    Thursday, July 12, 2012 5:02 PM

Answers

  • Look at Scenario 3 of the Media capture using capture device sampleHere's some condensed code from that sample showing how you use Windows.Media.Capture.MediaCapture for this purpose (which uses the default audio device):

    var mediaCaptureMgr = null;
    var captureInitSettings = null;
    var encodingProfile = null;
    var storageFile = null;
    // This is called when the page is loaded
    function initCaptureSettings() {
        captureInitSettings = null;
        captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
        captureInitSettings.audioDeviceId = "";
        captureInitSettings.videoDeviceId = "";
        captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
    }
    function startDevice() {
        mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
        mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
            // ...
        });
    }
    function startRecord() {
        // ...
        // Start recording.
        Windows.Storage.KnownFolders.videosLibrary.createFileAsync("cameraCapture.m4a",
            Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
            storageFile = newFile;
            encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(
                Windows.Media.MediaProperties.AudioEncodingQuality.auto);
            mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, storageFile)
           .done(function (result) {
                // ...
            });
        });
    }
    function stopRecord() {
        mediaCaptureMgr.stopRecordAsync().done(function (result) {
            displayStatus("Record Stopped.  File " + storageFile.path + "  ");
            // Playback the recorded audio
            var audio = id("capturePlayback" + scenarioId);
            audio.src = URL.createObjectURL(storageFile, { oneTimeOnly: true });
            audio.play();
        });
    }

    If you want to use a specific device, look at Scenario 2 for how to enumerate devices and provide a selection. The sample shows this for video, but should be easy enough to adapt for audio.

    .Kraig


    Thursday, July 12, 2012 5:30 PM

All replies

  • Look at Scenario 3 of the Media capture using capture device sampleHere's some condensed code from that sample showing how you use Windows.Media.Capture.MediaCapture for this purpose (which uses the default audio device):

    var mediaCaptureMgr = null;
    var captureInitSettings = null;
    var encodingProfile = null;
    var storageFile = null;
    // This is called when the page is loaded
    function initCaptureSettings() {
        captureInitSettings = null;
        captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
        captureInitSettings.audioDeviceId = "";
        captureInitSettings.videoDeviceId = "";
        captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
    }
    function startDevice() {
        mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
        mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
            // ...
        });
    }
    function startRecord() {
        // ...
        // Start recording.
        Windows.Storage.KnownFolders.videosLibrary.createFileAsync("cameraCapture.m4a",
            Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
            storageFile = newFile;
            encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(
                Windows.Media.MediaProperties.AudioEncodingQuality.auto);
            mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, storageFile)
           .done(function (result) {
                // ...
            });
        });
    }
    function stopRecord() {
        mediaCaptureMgr.stopRecordAsync().done(function (result) {
            displayStatus("Record Stopped.  File " + storageFile.path + "  ");
            // Playback the recorded audio
            var audio = id("capturePlayback" + scenarioId);
            audio.src = URL.createObjectURL(storageFile, { oneTimeOnly: true });
            audio.play();
        });
    }

    If you want to use a specific device, look at Scenario 2 for how to enumerate devices and provide a selection. The sample shows this for video, but should be easy enough to adapt for audio.

    .Kraig


    Thursday, July 12, 2012 5:30 PM
  • Kraig - Sorry to dig this out now, but I tried to run the Media Capture Using Capture Device sample, and I am getting "A machine name must be entered in the project properties page to debug the application remotely".

    Any ideas what I should be doing to run this app? I am also interested in recording audio then sending it to a server example.

    BTW - I am reading through your Programming Windows 8 Apps and I dig it so far. I am though chapter 2 already. Thanks for making the book available!

    cheers!

    gabster

    Wednesday, February 27, 2013 7:11 PM
  • Some of the samples have their projects set to Remote Machine debugging, which causes this kind of confusion (I certainly encountered it!). All you need to do is specify Local Machine (or Simulator) in the debug target on the toolbar:

    As for sending to a server, unless the server can handle streaming uploads (a scenario I haven't tried at all, so I don't know what's possible here), then I assume you'll be recording the file locally, then uploading. For the latter, use the Background Transfer API which you'll find discussed in Chapter 14 of my book and the Background Transfer sample.

    .Kraig

    Wednesday, February 27, 2013 7:37 PM
  • Thanks Kraig for your answer!

    I realized that the Solution Platform was set to ARM so I set it to x86 and then I was indeed able to choose Local Machine.

    I checked the Background Transfer API but that deals with the IIS server (at least at first sight). For the sake of not highjacking this thread, I'll probably leave it where it is, study the Background Transfer in chapter 14 in depth and open a new thread if needed be.

    thanks so much for help!

    Gabster

    Thursday, February 28, 2013 6:14 PM
  • Kraig -

    Sorry to bother you again. I am trying to strip down this media capture sample to strictly record audio. I was able to create a new project and display the audio control and the buttons correctly.

    However when I click on the Start Device button I am getting a:

    0x80070005 - JavaScript runtime error: Access is denied.
    WinRT information: Access is denied.

    on this line in AudioCapture.js (on the startDevice function):

    mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {

    Any idea what can be wrong?

    thanks!

    Thursday, February 28, 2013 7:58 PM
  • No problem.

    Do you have the Microphone capability checked in the manifest? If you're recording only audio, this is necessary separate from the Webcam capability. The lack of the capability would throw an access denied.

    You can also add an error function to .done which might give you more info, e.g.:

    mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
    }, function (e) {
    });

    When the error throws, look at the contents of the e argument, as often it'll have more specific information.

    .Kraig

    Friday, March 01, 2013 3:54 AM
  • Kraig!

    Thanks much for the answer! Things are looking better after checking the Microphone capability. Now I am only getting an SdkSample is undefined on the:

        function displayStatus(statusText) {
            SdkSample.displayStatus(statusText);
        }

    I discovered that the definition of that name space resides in the sample-utils.js file and looks like this:

        // Export public methods & controls
        WinJS.Namespace.define("SdkSample", {
            ScenarioInput: ScenarioInput,
            ScenarioOutput: ScenarioOutput
        });

    Should I bring that definition over into my AudioCapture.js in my project? In that case where should I plop it?

    I had to specify that I only have AudioCapture.js in my project. None of the other js files from the media capture sample are present. I only want to strictly use the code pertaining to the audio recording scenario.

    MANY thanks!

    gabi.

    Friday, March 01, 2013 8:45 PM
  • No need. All that stuff is just to set up the input/output panes that are common to the SDK samples. It's not part of what the sample is demonstrating.
    Friday, March 01, 2013 8:53 PM
  • Thanks Kraig -

    I went on and commented all the displayStatus calls. Looks like the Device is on but when I click the Record button, the next error I get is:

    0x800a138f - JavaScript runtime error: Unable to get property 'paused' of undefined or null reference

    on this line (in the startRecord function):

     if (!video.paused)

    That shouldn't even be in the AudioCapture.js right?

    thanks !

    Friday, March 01, 2013 9:22 PM
  • Kraig -

    Please disregard my previous question. I discovered that I still had id="capturePlayback3" in my home.html instead of id="capturePlayback" as I was setting it from var video = id("capturePlayback");

    it works now! On to chapter 14. Thanks for all your help!

    gabster

    Monday, March 04, 2013 7:09 PM
  • Yes, that would do it :). Glad you got it working!

    Monday, March 04, 2013 8:20 PM