Adobe record sound and save

2020-04-21 02:26发布

问题:

In the following code i am trying to save the microphone contents to a file.The saved file doesn't play and Every time the file is saved i see that the size is only of 10 bytes only.What am i doing wrong in the code.Can someone please show me the correct code to save it .And the saved file should play the recorded contents accordingly.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
    <![CDATA[
        import flash.events.SampleDataEvent; 
        import flash.media.Microphone;
        import flash.net.FileReference;
        import mx.controls.Alert;
        import flash.net.FileReference;
        import flash.display.Sprite;
        import flash.media.Sound;
        import flash.utils.ByteArray;
        import flash.external.ExternalInterface;




        public var _file:FileReference = new FileReference();
        [Bindable] private var micList:Array;
        public var mic:Microphone = Microphone.getMicrophone();
        protected var isRecording:Boolean = false;

        protected function startMicRecording():void 
        { 
            //var mic:Microphone = Microphone.getMicrophone();
            mic.gain = 60;
            mic.rate = 11;
            mic.setUseEchoSuppression(true);
            mic.setLoopBack(true);
            mic.setSilenceLevel(5, 1000);
            Alert.show("In recording");
            isRecording = true;
            mic.addEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);

        }

        protected function stopMicRecording():void 
        { 


            //isRecording = false;

            try{
            //_file.save( SampleDataEvent.SAMPLE_DATA, "recorded.wav" );
                _file.save(SampleDataEvent.SAMPLE_DATA , "recorded.flv" );
            }
            catch(e:Error)
            {
                Alert.show("In Stopmicrecording"+e);
            }

        }

        private function gotMicData(micData:SampleDataEvent):void 
        { 

            //mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);

        }


        protected var soundRecording:ByteArray;
        protected var soundOutput:Sound;
        protected function playbackData():void 
        { 



        } 

        private function playSound(soundOutput:SampleDataEvent):void
        {

        }







    ]]>
</fx:Script>
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:ComboBox x="150" id="comboMicList" dataProvider="{micList}" />
<mx:Button x="250" id="startmicrec" label="Start Rec" click="startMicRecording()"/>
<mx:Button x="350" id="stopmicrec" label="Stop Rec" click="stopMicRecording()"/> 
<!--<mx:Button x="50" id="setupmic" label="Select Mic" click="setupMicrophone()"/>-->
<mx:Button x="450" id="playrecsound" label="Play sound" click="playbackData()"/>

 </s:Application>

回答1:

You need to store the data that is handed to you in gotMicData into a ByteArray and then save that ByteArray. You are saving the event name, which is a string (10 characters long).

Once you do that, you need to load the file and hand sample data to the sound. You play the sound back 8 times... because you sampled at 11 KHz but the sound plays back at 44 KHz (4x writing) and the sound is Stereo but the mic is mono (2x again).

You can't save the data as a WAV file directly... you recorded raw data. If you want to go through the trouble of writing a proper WAV header, then you don't have to play the games of handing sample data and hand the file to the Sound object. That is an exercise outside of the scope of this question.

Good luck!

        import mx.controls.Alert;

        public var mic:Microphone = Microphone.getMicrophone();
        public var recordedData:ByteArray;

        protected function startMicRecording():void 
        { 
            mic.gain = 60;
            mic.rate = 11;
            mic.setUseEchoSuppression(true);
            mic.setLoopBack(false);
            mic.setSilenceLevel(5, 1000);

            recordedData = new ByteArray();
            mic.addEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);

        }

        protected function stopMicRecording():void 
        { 
            mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);

            try{
                var file:FileReference = new FileReference();
                file.save(recordedData, "recorded.dat" );
            }
            catch(e:Error)
            {
                Alert.show("In Stopmicrecording"+e);
            }

        }

        private function gotMicData(sample:SampleDataEvent):void 
        { 
            recordedData.writeBytes(sample.data, 0, sample.data.bytesAvailable);
        }


        protected var playbackFile:FileReference;
        protected var soundRecording:ByteArray;
        protected var soundOutput:Sound;
        protected function playbackData():void 
        { 
            playbackFile = new FileReference();
            playbackFile.addEventListener(Event.SELECT, playbackFileSelected);
            playbackFile.browse();
        } 

        private function playbackFileSelected(event:Event):void {
            playbackFile.addEventListener(Event.COMPLETE, playbackFileLoaded);
            playbackFile.load();
        }

        private function playbackFileLoaded(event:Event):void {
            soundRecording = playbackFile.data;
            soundOutput = new Sound();
            soundOutput.addEventListener(SampleDataEvent.SAMPLE_DATA, moreInput);
            soundOutput.play();
        }

        private function moreInput(event:SampleDataEvent):void {
            var sample:Number;
            for (var i:int = 0; i < 1024; i++) {
                if (soundRecording.bytesAvailable > 0) {
                    sample = soundRecording.readFloat();

                    // write the same byte 8 times:
                    //   Upsample from 11 KHz to 44 KHz (x4)
                    //   Mono to Stereo (x2)
                    for(var x:int = 0; x < 8; x++)
                        event.data.writeFloat(sample);
                }
            }
        }