将麦克风音频发送到服务器

时间:2014-01-23 13:05:51

标签: c# windows-phone-7 windows-phone-8 windows-phone

我想从麦克风录制音频,将其转换为base64字符串,然后将其发送到服务器。

然后服务器在.wav文件中转换base64字符串。

我的C#代码:

   IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(Filename, FileMode.Create, myIsolatedStorage);
   fileStream.Write(stream.GetBuffer(), 0, (int)stream.Position);

   fileStream.Position = 0;



        // Convert to base64 string and then urlencode it:

byte[] binaryData = new Byte[fileStream.Length];
long bytesRead = fileStream.Read(binaryData, 0, (int)fileStream.Length);
string fileBase64 = System.Convert.ToBase64String(binaryData, 0, binaryData.Length);               
fileBase64 = HttpUtility.UrlEncode(fileBase64);



        // Send it to server:


        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://.../upload.php");
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";

        string postData = String.Format("file={0}", fileBase64);   

        // Getting the request stream.
        request.BeginGetRequestStream
            (result =>
            {
                // Sending the request.
                using (var requestStream = request.EndGetRequestStream(result))
                {
                    using (StreamWriter writer = new StreamWriter(requestStream))
                    {
                        writer.Write(postData);
                        writer.Flush();
                    }
                }

                // Getting the response.
                request.BeginGetResponse(responseResult =>
                {
                    var webResponse = request.EndGetResponse(responseResult);
                    using (var responseStream = webResponse.GetResponseStream())
                    {
                        using (var streamReader = new StreamReader(responseStream))
                        {
                            string srresult = streamReader.ReadToEnd();
                        }
                    }
                }, null);
            }, null);

然后我的php脚本会收到一个像“+ / 8cADkAOQAWAPD / 7f / 5 ...”这样的base64字符串,然后将其转换为带有 base64_decode php函数的.wav文件。但是如果我用VLC打开这个文件,它就不会重现任何东西。

如果我以这种方式打开文件(见下文),就在我保存之后,它会再现声音:

 byte[] buffer = new byte[microphone.GetSampleSizeInBytes(duration)];
 using (IsolatedStorageFile userStore = IsolatedStorageFile.GetUserStoreForApplication())
 using (IsolatedStorageFileStream openfilestream = userStore.OpenFile(Filename, FileMode.Open))
            {
                openfilestream.Read(buffer, 0, buffer.Length);
            }

  SoundEffect sound = new SoundEffect(buffer, microphone.SampleRate, AudioChannels.Mono);
  soundInstance = sound.CreateInstance();
  soundIsPlaying = true;
  soundInstance.Play();

1 个答案:

答案 0 :(得分:1)

您正在保存(并使用SoundEffect)原始音频数据。

WAVE文件不仅仅是数据,而且它也有标题(因为位图文件不仅仅是一个像素序列)。如果您想使用程序播放它,则需要使用标题保存它:请参阅specifications

你很幸运,它很简单,所以你可以做这样的事情(未经测试和非常原始只是为了说明目的,当你将原始流转换为WAVE时你必须做服务器端):

// First 4 bytes are file format marker. Container file format
// is RIFF (it's a tagged file format)
streamWriter.Write(Encoding.ASCII.GetBytes("RIFF"));

// Number of bytes, header + audio samples
streamWriter.Write(36 + sampleCount * channelCount * samplingRate);

// Beginning of chunk specific of WAVE files, it describe how
// data are stored
streamWriter.Write(Encoding.ASCII.GetBytes("WAVEfmt "));
streamWriter.Write(16); // It's always 16 bytes

// Audio stream is PCM (value 1)
streamWriter.Write((UInt16)1);

// Player will use these information to understand how samples
// are stored in the stream.
streamWriter.Write(channelCount);
streamWriter.Write(samplingRate);
streamWriter.Write(samplingRate * bytesPerSample * channelCount);
streamWriter.Write(bytesPerSample * channelCount);
streamWriter.Write((UInt16)(8 * bytesPerSample));

// Now the chunk that contains audio stream, just add its marker
// and its length then write all your samples (in the raw format you have)
streamWriter.Write(Encoding.ASCII.GetBytes("data"));
streamWriter.Write(sampleCount * bytesPerSample);