WindowsPhone7录音-IsolatedStorage保存wav文件-IsolatedStorage上传wav录音文件(完整版)

之前尝试了用webservice上传wav录音文件失败了,以为是工程上传的问题,现在改用Webclient上传,然后发现先前的想法是错的。。。。。

过程:在xaml中放一个按钮,按住的时候录音,放开后保存录音,并上传

在前台定义button的ManipulationStarted和ManipulationCompleted 事件,然后开始了----

一堆微软的东西拿进去:

        //麦克单例
private Microphone microphone = Microphone.Default;
//每次捕获音频缓存
private byte[] buf;
//音频流存储区
private MemoryStream audioStream;
void microphone_BufferReady(object sender, EventArgs e)
{
//将麦克风的数据复制到缓冲区中
microphone.GetData(buf);
//将该缓冲区写入一个流
audioStream.Write(buf, 0, buf.Length);
}
/// <summary>
/// 写wav文件头信息 某位大牛写的保存wav的方法,这里放出链接
///http://damianblog.com/2011/02/07/storing-wp7-recorded-audio-as-wav-format-streams/
/// </summary>
/// <param name="stream"></param>
/// <param name="sampleRate"></param>
public void WriteWavHeader(Stream stream, int sampleRate)
{
const int bitsPerSample = 16;
const int bytesPerSample = bitsPerSample / 8;
var encoding = System.Text.Encoding.UTF8;

// ChunkID Contains the letters "RIFF" in ASCII form (0x52494646 big-endian form).
stream.Write(encoding.GetBytes("RIFF"), 0, 4);

// NOTE this will be filled in later
stream.Write(BitConverter.GetBytes(0), 0, 4);

// Format Contains the letters "WAVE"(0x57415645 big-endian form).
stream.Write(encoding.GetBytes("WAVE"), 0, 4);

// Subchunk1ID Contains the letters "fmt " (0x666d7420 big-endian form).
stream.Write(encoding.GetBytes("fmt "), 0, 4);

// Subchunk1Size 16 for PCM. This is the size of therest of the Subchunk which follows this number.
stream.Write(BitConverter.GetBytes(16), 0, 4);

// AudioFormat PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression.
stream.Write(BitConverter.GetBytes((short)1), 0, 2);

// NumChannels Mono = 1, Stereo = 2, etc.
stream.Write(BitConverter.GetBytes((short)1), 0, 2);

// SampleRate 8000, 44100, etc.
stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);

// ByteRate = SampleRate * NumChannels * BitsPerSample/8
stream.Write(BitConverter.GetBytes(sampleRate * bytesPerSample), 0, 4);

// BlockAlign NumChannels * BitsPerSample/8 The number of bytes for one sample including all channels.
stream.Write(BitConverter.GetBytes((short)(bytesPerSample)), 0, 2);

// BitsPerSample 8 bits = 8, 16 bits = 16, etc.
stream.Write(BitConverter.GetBytes((short)(bitsPerSample)), 0, 2);

// Subchunk2ID Contains the letters "data" (0x64617461 big-endian form).
stream.Write(encoding.GetBytes("data"), 0, 4);

// NOTE to be filled in later
stream.Write(BitConverter.GetBytes(0), 0, 4);
}
/// <summary>
/// 更新wav文件头信息
/// </summary>
/// <param name="stream"></param>
public void UpdateWavHeader(Stream stream)
{
if (!stream.CanSeek) throw new Exception("Can't seek stream to update wav header");

var oldPos = stream.Position;

// ChunkSize 36 + SubChunk2Size
stream.Seek(4, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);

// Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
stream.Seek(40, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);

stream.Seek(oldPos, SeekOrigin.Begin);
}


然后是ManipulationStarted和ManipulationCompleted

        private void Button_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
//话说没有这一步会报错 Update has not been called
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(33);
timer.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
timer.Start();

//设置1秒的缓存区,没获取1秒音频就会调用一次BufferReady事件
microphone.BufferDuration = TimeSpan.FromMilliseconds(1000);
//分配1秒音频所需要的缓存区
buf = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
audioStream = new MemoryStream();
//BufferReady事件
microphone.BufferReady += new EventHandler<EventArgs>(microphone_BufferReady);
//写wav文件头
WriteWavHeader(audioStream, microphone.SampleRate);
//启动录音
microphone.Start();
}
private void Button_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
//修改文件头
UpdateWavHeader(audioStream);
//停止录音
microphone.Stop();
microphone.BufferReady -= new EventHandler<EventArgs>(microphone_BufferReady);
audioStream.Flush();
//将数据流转换为byte,recording中即为音频数据
byte[] recording = audioStream.ToArray();
// byte[] uploadFileStream = ReadToEnd(audioStream);
audioStream.Dispose();
//播放录音
SoundEffect sound = new SoundEffect(audioStream.ToArray(), microphone.SampleRate, AudioChannels.Mono);
sound.Play();


//string wavFile = "temp.wav";
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
//if (myIsolatedStorage.FileExists(wavFile)) { myIsolatedStorage.DeleteFile(wavFile); }
try
{
// 打开文件
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("temp.wav", FileMode.Create, myIsolatedStorage))
{
fileStream.Write(recording, 0, recording.Length);
}
}
catch
{
// 读取失败
}
}
Upload();
}

从IsolatedStorage读取文件,上传

public void Upload()
{
UriBuilder ub = new UriBuilder("http://localhost:13235/WebClientUpLoadHandler.ashx");
ub.Query = string.Format("name={0}", "helloworld.wav");
WebClient c = new WebClient();
c.OpenWriteCompleted += (sender1, e1) =>
{
System.IO.IsolatedStorage.IsolatedStorageFile isf =
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
System.IO.IsolatedStorage.IsolatedStorageFileStream data =
new System.IO.IsolatedStorage.IsolatedStorageFileStream(
"temp.wav",
System.IO.FileMode.Open,
isf);

PushData(data, e1.Result);
e1.Result.Close();
data.Close();
};
c.OpenWriteAsync(ub.Uri);
}

接下来是server端:

新建一个ashx 文件,处理上传数据

/// <summary>
/// 处理上传
/// </summary>
public class WebClientUpLoadHandler : IHttpHandler
{
public string name;
public void ProcessRequest(HttpContext context)
{
//获取从Silverlight客户端传来的信息
int length = context.Request.ContentLength;
byte[] bytes = context.Request.BinaryRead(length);
name = context.Request.QueryString["name"];
string uploadFolder = System.AppDomain.CurrentDomain.BaseDirectory + "\\uploadvoice";
//目录不存在则新建
//if (!System.IO.Directory.Exists(uploadFolder))
//{
// System.IO.Directory.CreateDirectory(uploadFolder);
//}
System.IO.FileMode fileMode = System.IO.FileMode.Create;
////写入文件
try
{
using (System.IO.FileStream fs = new System.IO.FileStream(uploadFolder + "\\" + name, fileMode, System.IO.FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
} context.Response.Write("服务器端成功");
}
catch { context.Response.Write("写入失败"); }


}

public bool IsReusable
{
get
{
return false;
}
}

}

博客地址http://www.cnblogs.com/shit 引用请说明出处

posted @ 2012-03-19 14:52  newShit  阅读(1962)  评论(8编辑  收藏  举报