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 引用請說明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM