zoukankan      html  css  js  c++  java
  • 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 引用请说明出处

  • 相关阅读:
    Linux C Socket编程原理及简单实例
    clock_gettime 用法
    Linux未来监控tracing框架——eBPF
    eBPF监控工具bcc系列五工具funccount
    【转】如何测量电源纹波?
    【转】在网页中运行VB6程序
    如何为互阻抗放大器电路选择具有足够带宽的运算放大器
    互阻放大器的稳定工作及其评估
    【原创】OPA857 TEST模式使用
    [转]What you need to know about transimpedance amplifiers – part 1
  • 原文地址:https://www.cnblogs.com/shit/p/2406085.html
Copyright © 2011-2022 走看看