代码改变世界

Silverlight4调用本地音频设备并将音频文件上传到服务器

2013-03-15 16:30  suzh  阅读(320)  评论(0编辑  收藏  举报

•前言

  今天遇到一个技术上的难题,如何通过web端调用本地音频设备并将音频文件上传到服务器?在网上搜集了很多资料,最终整理出来了一个版本,但还是无法满足目前的需求,借着这个机会,将源码贴出来给大家分享,希望能得到高手的指点,解决自己的困惑。好了,废话不多说,进入正题。(部分代码源自其他网友,因为无法追溯出处,在本文中未署名原创作者信息,如有侵权,请告知)

•思路

  目前调用本地音频设备常用的方式有三种:

  1)在web项目中引用DirectX.dll。但是本人愚钝,结合网上的知识,没有得到想要的结果,所以pass;

  2)在网上搜集Flash插件。好嘛,在网上搜集的一些Demo大多数都是一些极其简单的,并不能满足需求。缺点:只能将音频文件保存到本地;无法获取保存后的文件路径;样式太丑;很多东西无法自定义,如录音时间、保存格式等等,所以pass;

  3)通过Silverlight调用本地音频设备。这是目前自己觉得最好的解决方案。

  下面我将介绍如何通过Silverlight4调用本地音频设备并将音频文件上传到服务器。

•正文

  项目整体目录结构

  

  其中,AudioUpload.asmx在SL端进行引用,用于上传音频文件;VoiceControlTestPage.aspx引用了Silverlight xap包。

  界面效果图:

  

  点击开始录音,程序会调用音频设备,开始录音,计时开始;点击保存录音,将内存流转换为WAV文件,并调用webService上传。

  下面将不一一介绍了,如实贴出源码:

MainPage.xaml   

View Code

<UserControl x:Class="VoiceControl.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="55" d:DesignWidth="175">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="35"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button Name="btnRecord"  Content="开始录音" Grid.Row="0" Grid.Column="0" Margin="5,5,5,5"  Click="btnRecord_Click" />
        <Button Name="btnSaveWav" Content="保存录音" Grid.Row="0" Grid.Column="1" Margin="5,5,5,5"  Click="btnSaveWav_Click" />
        <TextBlock Name="txtAudioTime" Grid.Row="2" Grid.ColumnSpan="2" TextAlignment="Center">00:00</TextBlock>
    </Grid>
</UserControl>

 

MainPage.xaml.cs  

View Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using VoiceControl.AudioUploadServiceReference;
using System.IO.IsolatedStorage;
using System.Windows.Browser;
using System.Windows.Threading;

namespace VoiceControl
{
    public partial class MainPage : UserControl
    {
        //声明私有变量
        private WavAudioSink _wavSink;
        private CaptureSource _captureSource;
        private SaveFileDialog _saveFileDialog = new SaveFileDialog() { Filter = "Audio files (*.wav)|*.wav" };
        private DispatcherTimer timer = new DispatcherTimer();

        #region 自定义属性
        /// <summary>
        /// 生成的WAV文件名
        /// </summary>
        public string FileName { get; set; }
        /// <summary>
        /// 分钟
        /// </summary>
        public int TimerMinute { get; set; }
        /// <summary>
        /// 秒
        /// </summary>
        public int TimerSecond { get; set; }

        #endregion

        public MainPage()
        {
            InitializeComponent();
            btnRecord.IsEnabled = true;
            btnSaveWav.IsEnabled = false;
            //计时器设置
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += new EventHandler(timer_Tick);
        }

        private void btnRecord_Click(object sender, RoutedEventArgs e)
        {
            //初始化_captureSource
            var audioDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();
            _captureSource = new CaptureSource() { AudioCaptureDevice = audioDevice };

            //有默认设置的设备且可以用来录制音频
            if (CaptureDeviceConfiguration.AllowedDeviceAccess ||
                CaptureDeviceConfiguration.RequestDeviceAccess())
            {
                //判断当前没有开始录制音频
                if (_captureSource.State == CaptureState.Stopped)
                {
                    //初始化WavAudioSink
                    _wavSink = new WavAudioSink();
                    _wavSink.CaptureSource = _captureSource;
                    //开始录制音频
                    _captureSource.Start();
                }
                btnRecord.IsEnabled = false;
                btnSaveWav.IsEnabled = true;
                //开始计时
                timer.Start();
            }
            else
            {
                MessageBox.Show("客户端未捕捉到音频设备,无法使用录音功能", "提示", MessageBoxButton.OK);
                btnRecord.IsEnabled = false;
                btnSaveWav.IsEnabled = false;
            }
        }

        //Timer计时事件
        void timer_Tick(object sender, EventArgs e)
        {
            if (TimerSecond == 59)
            {
                TimerMinute += 1;
                TimerSecond = 0;
            }
            else
            {
                TimerSecond += 1;
            }
            txtAudioTime.Text = (TimerMinute > 9 ? TimerMinute.ToString() : "0" + TimerMinute.ToString()) + ":" + 
                                (TimerSecond > 9 ? TimerSecond.ToString() : "0" + TimerSecond.ToString());
        }

        private void btnSaveWav_Click(object sender, RoutedEventArgs e)
        {
            //结束计时
            timer.Stop();
            this.TimerMinute = 0;
            this.TimerSecond = 0;
            this.txtAudioTime.Text = "00:00";

            //如果当前状态为开始录制,则停止录制
            if (_captureSource.State == CaptureState.Started)
            {
                _captureSource.Stop();
            }

            #region 保存Wav文件 version 2.0

            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication() )
            {
                //默认存储空间大小
                long defaultQutaSize = store.Quota;
                //独立存储空间大小(1G)
                long newQutaSize = 1024 * 1024 * 1024;
                //客户端第一次运行本程序会提示将存储空间提升为1G容量
                if (defaultQutaSize < newQutaSize)
                {
                    store.IncreaseQuotaTo(newQutaSize);
                }
                using (IsolatedStorageFileStream stream = store.CreateFile(Guid.NewGuid().ToString() + ".wav"))
                {
                    SaveWAVHelper.SavePcmToWav(_wavSink.BackingStream, stream, _wavSink.CurrentFormat);
                    btnRecord.IsEnabled = true;
                    btnSaveWav.IsEnabled = false;
                    //将保存到本地的Wav文件保存到服务器端
                    FileName = Guid.NewGuid().ToString() + ".wav";
                    stream.Position = 0;
                    byte[] buffer = new byte[stream.Length + 1];
                    stream.Read(buffer, 0, buffer.Length);
                    AudioUploadSoapClient webClient = new AudioUploadSoapClient();
                    webClient.UploadMyAudioCompleted += new EventHandler<UploadMyAudioCompletedEventArgs>(webClient_UploadMyAudioCompleted);
                    webClient.UploadMyAudioAsync(buffer, FileName);
                    stream.Close();
                }
                //清除独立存储空间,防止存储空间不足
                var listFile = store.GetFileNames();
                if (listFile != null && listFile.Count<string>() > 0)
                {
                    foreach (string item in listFile)
                    {
                        store.DeleteFile(item);
                    }
                }
            }
            #endregion

            #region 保存Wav文件 version 1.0

            /*
            Stream stream = _saveFileDialog.OpenFile();
            SaveWAVHelper.SavePcmToWav(_wavSink.BackingStream, stream, _wavSink.CurrentFormat);

            btnRecord.IsEnabled = true;
            btnSaveWav.IsEnabled = false;

            //将保存到本地的Wav文件保存到服务器端
            string filename = Guid.NewGuid().ToString() + ".wav";
            stream.Position = 0;
            byte[] buffer = new byte[stream.Length + 1];
            stream.Read(buffer, 0, buffer.Length);

            AudioUploadSoapClient webClient = new AudioUploadSoapClient();
            webClient.UploadMyAudioCompleted += new EventHandler<UploadMyAudioCompletedEventArgs>(webClient_UploadMyAudioCompleted);
            webClient.UploadMyAudioAsync(buffer, filename);

            stream.Close();
            */
            #endregion
        }

        void webClient_UploadMyAudioCompleted(object sender, UploadMyAudioCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                var app = App.Current as App;
                HtmlPage.Window.CreateInstance("ajaxTest", HtmlPage.Document.QueryString["userid"], HtmlPage.Document.QueryString["age"], FileName);
            }
        }

        private string GetParameter(string key)
        {
            if (App.Current.Resources[key] != null)
            {
                return App.Current.Resources[key].ToString();
            }
            else
            {
                return string.Empty;
            }
        }
    }
}

  


复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using VoiceControl.AudioUploadServiceReference;
using System.IO.IsolatedStorage;
using System.Windows.Browser;
using System.Windows.Threading;

namespace VoiceControl
{
    public partial class MainPage : UserControl
    {
        //声明私有变量
        private WavAudioSink _wavSink;
        private CaptureSource _captureSource;
        private SaveFileDialog _saveFileDialog = new SaveFileDialog() { Filter = "Audio files (*.wav)|*.wav" };
        private DispatcherTimer timer = new DispatcherTimer();

        #region 自定义属性
        /// <summary>
        /// 生成的WAV文件名
        /// </summary>
        public string FileName { get; set; }
        /// <summary>
        /// 分钟
        /// </summary>
        public int TimerMinute { get; set; }
        /// <summary>
        /// 秒
        /// </summary>
        public int TimerSecond { get; set; }

        #endregion

        public MainPage()
        {
            InitializeComponent();
            btnRecord.IsEnabled = true;
            btnSaveWav.IsEnabled = false;
            //计时器设置
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += new EventHandler(timer_Tick);
        }

        private void btnRecord_Click(object sender, RoutedEventArgs e)
        {
            //初始化_captureSource
            var audioDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();
            _captureSource = new CaptureSource() { AudioCaptureDevice = audioDevice };

            //有默认设置的设备且可以用来录制音频
            if (CaptureDeviceConfiguration.AllowedDeviceAccess ||
                CaptureDeviceConfiguration.RequestDeviceAccess())
            {
                //判断当前没有开始录制音频
                if (_captureSource.State == CaptureState.Stopped)
                {
                    //初始化WavAudioSink
                    _wavSink = new WavAudioSink();
                    _wavSink.CaptureSource = _captureSource;
                    //开始录制音频
                    _captureSource.Start();
                }
                btnRecord.IsEnabled = false;
                btnSaveWav.IsEnabled = true;
                //开始计时
                timer.Start();
            }
            else
            {
                MessageBox.Show("客户端未捕捉到音频设备,无法使用录音功能", "提示", MessageBoxButton.OK);
                btnRecord.IsEnabled = false;
                btnSaveWav.IsEnabled = false;
            }
        }

        //Timer计时事件
        void timer_Tick(object sender, EventArgs e)
        {
            if (TimerSecond == 59)
            {
                TimerMinute += 1;
                TimerSecond = 0;
            }
            else
            {
                TimerSecond += 1;
            }
            txtAudioTime.Text = (TimerMinute > 9 ? TimerMinute.ToString() : "0" + TimerMinute.ToString()) + ":" + 
                                (TimerSecond > 9 ? TimerSecond.ToString() : "0" + TimerSecond.ToString());
        }

        private void btnSaveWav_Click(object sender, RoutedEventArgs e)
        {
            //结束计时
            timer.Stop();
            this.TimerMinute = 0;
            this.TimerSecond = 0;
            this.txtAudioTime.Text = "00:00";

            //如果当前状态为开始录制,则停止录制
            if (_captureSource.State == CaptureState.Started)
            {
                _captureSource.Stop();
            }

            #region 保存Wav文件 version 2.0

            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication() )
            {
                //默认存储空间大小
                long defaultQutaSize = store.Quota;
                //独立存储空间大小(1G)
                long newQutaSize = 1024 * 1024 * 1024;
                //客户端第一次运行本程序会提示将存储空间提升为1G容量
                if (defaultQutaSize < newQutaSize)
                {
                    store.IncreaseQuotaTo(newQutaSize);
                }
                using (IsolatedStorageFileStream stream = store.CreateFile(Guid.NewGuid().ToString() + ".wav"))
                {
                    SaveWAVHelper.SavePcmToWav(_wavSink.BackingStream, stream, _wavSink.CurrentFormat);
                    btnRecord.IsEnabled = true;
                    btnSaveWav.IsEnabled = false;
                    //将保存到本地的Wav文件保存到服务器端
                    FileName = Guid.NewGuid().ToString() + ".wav";
                    stream.Position = 0;
                    byte[] buffer = new byte[stream.Length + 1];
                    stream.Read(buffer, 0, buffer.Length);
                    AudioUploadSoapClient webClient = new AudioUploadSoapClient();
                    webClient.UploadMyAudioCompleted += new EventHandler<UploadMyAudioCompletedEventArgs>(webClient_UploadMyAudioCompleted);
                    webClient.UploadMyAudioAsync(buffer, FileName);
                    stream.Close();
                }
                //清除独立存储空间,防止存储空间不足
                var listFile = store.GetFileNames();
                if (listFile != null && listFile.Count<string>() > 0)
                {
                    foreach (string item in listFile)
                    {
                        store.DeleteFile(item);
                    }
                }
            }
            #endregion

            #region 保存Wav文件 version 1.0

            /*
            Stream stream = _saveFileDialog.OpenFile();
            SaveWAVHelper.SavePcmToWav(_wavSink.BackingStream, stream, _wavSink.CurrentFormat);

            btnRecord.IsEnabled = true;
            btnSaveWav.IsEnabled = false;

            //将保存到本地的Wav文件保存到服务器端
            string filename = Guid.NewGuid().ToString() + ".wav";
            stream.Position = 0;
            byte[] buffer = new byte[stream.Length + 1];
            stream.Read(buffer, 0, buffer.Length);

            AudioUploadSoapClient webClient = new AudioUploadSoapClient();
            webClient.UploadMyAudioCompleted += new EventHandler<UploadMyAudioCompletedEventArgs>(webClient_UploadMyAudioCompleted);
            webClient.UploadMyAudioAsync(buffer, filename);

            stream.Close();
            */
            #endregion
        }

        void webClient_UploadMyAudioCompleted(object sender, UploadMyAudioCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                var app = App.Current as App;
                HtmlPage.Window.CreateInstance("ajaxTest", HtmlPage.Document.QueryString["userid"], HtmlPage.Document.QueryString["age"], FileName);
            }
        }

        private string GetParameter(string key)
        {
            if (App.Current.Resources[key] != null)
            {
                return App.Current.Resources[key].ToString();
            }
            else
            {
                return string.Empty;
            }
        }
    }
}
复制代码

SaveWAVHelper.cs   (WAV文件转换辅助类)

View Code

/*********************************
 * Author:袁形
 * Date:2012-12-18
 * Version:1.0
 * Description:将内存流转换为wav文件
 *********************************/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace VoiceControl
{
    public class SaveWAVHelper
    {
        public static void SavePcmToWav(Stream rawData, Stream output, AudioFormat audioFormat)
        {
            if (audioFormat.WaveFormat != WaveFormatType.Pcm)
                throw new ArgumentException("不支持使用非脉冲编码调制(Pcm)编码的音频格式");

            BinaryWriter bwOutput = new BinaryWriter(output);

            // -- RIFF 块
            bwOutput.Write("RIFF".ToCharArray());
            // 包的总长度
            // 计算的数据长度加上数据头的长度没有数据
            // 写数据(44 - 4 ("RIFF") - 4 (当前数据))
            bwOutput.Write((uint)(rawData.Length + 36));
            bwOutput.Write("WAVE".ToCharArray());

            // -- FORMAT 块
            bwOutput.Write("fmt ".ToCharArray());
            // FORMAT 块的长度 (Binary, 总是 0x10)
            bwOutput.Write((uint)0x10);
            // 总是 0x01
            bwOutput.Write((ushort)0x01);
            // 通道数( 0x01=单声道, 0x02=立体声)
            bwOutput.Write((ushort)audioFormat.Channels);
            // 采样率 (Binary,  Hz为单位)
            bwOutput.Write((uint)audioFormat.SamplesPerSecond);
            // 字节每秒
            bwOutput.Write((uint)(audioFormat.BitsPerSample * audioFormat.SamplesPerSecond *
                audioFormat.Channels / 8));
            // 每个样品字节: 1=8 bit 单声道, 2=8 bit 立体声 or 16 bit 单声道, 4=16 bit 立体声
            bwOutput.Write((ushort)(audioFormat.BitsPerSample * audioFormat.Channels / 8));
            // 每个样品字节
            bwOutput.Write((ushort)audioFormat.BitsPerSample);

            // -- DATA 块
            bwOutput.Write("data".ToCharArray());
            // DATA数据块的长度
            bwOutput.Write((uint)rawData.Length);
            // 原始PCM数据如下
            // 复位rawData地位,记住它的原点位置
            // 恢复底。
            long originalRawDataStreamPosition = rawData.Position;
            rawData.Seek(0, SeekOrigin.Begin);
            //追加到输出流中的所有数据从rawData流
            byte[] buffer = new byte[4096];
            int read;
            // 循环读取字节数据
            while ((read = rawData.Read(buffer, 0, 4096)) > 0)
            {
                bwOutput.Write(buffer, 0, read);
            }
            //开始写入数据
            rawData.Seek(originalRawDataStreamPosition, SeekOrigin.Begin);
        }
    }
}

  


复制代码
/*********************************
 * Author:袁形
 * Date:2012-12-18
 * Version:1.0
 * Description:将内存流转换为wav文件
 *********************************/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace VoiceControl
{
    public class SaveWAVHelper
    {
        public static void SavePcmToWav(Stream rawData, Stream output, AudioFormat audioFormat)
        {
            if (audioFormat.WaveFormat != WaveFormatType.Pcm)
                throw new ArgumentException("不支持使用非脉冲编码调制(Pcm)编码的音频格式");

            BinaryWriter bwOutput = new BinaryWriter(output);

            // -- RIFF 块
            bwOutput.Write("RIFF".ToCharArray());
            // 包的总长度
            // 计算的数据长度加上数据头的长度没有数据
            // 写数据(44 - 4 ("RIFF") - 4 (当前数据))
            bwOutput.Write((uint)(rawData.Length + 36));
            bwOutput.Write("WAVE".ToCharArray());

            // -- FORMAT 块
            bwOutput.Write("fmt ".ToCharArray());
            // FORMAT 块的长度 (Binary, 总是 0x10)
            bwOutput.Write((uint)0x10);
            // 总是 0x01
            bwOutput.Write((ushort)0x01);
            // 通道数( 0x01=单声道, 0x02=立体声)
            bwOutput.Write((ushort)audioFormat.Channels);
            // 采样率 (Binary,  Hz为单位)
            bwOutput.Write((uint)audioFormat.SamplesPerSecond);
            // 字节每秒
            bwOutput.Write((uint)(audioFormat.BitsPerSample * audioFormat.SamplesPerSecond *
                audioFormat.Channels / 8));
            // 每个样品字节: 1=8 bit 单声道, 2=8 bit 立体声 or 16 bit 单声道, 4=16 bit 立体声
            bwOutput.Write((ushort)(audioFormat.BitsPerSample * audioFormat.Channels / 8));
            // 每个样品字节
            bwOutput.Write((ushort)audioFormat.BitsPerSample);

            // -- DATA 块
            bwOutput.Write("data".ToCharArray());
            // DATA数据块的长度
            bwOutput.Write((uint)rawData.Length);
            // 原始PCM数据如下
            // 复位rawData地位,记住它的原点位置
            // 恢复底。
            long originalRawDataStreamPosition = rawData.Position;
            rawData.Seek(0, SeekOrigin.Begin);
            //追加到输出流中的所有数据从rawData流
            byte[] buffer = new byte[4096];
            int read;
            // 循环读取字节数据
            while ((read = rawData.Read(buffer, 0, 4096)) > 0)
            {
                bwOutput.Write(buffer, 0, read);
            }
            //开始写入数据
            rawData.Seek(originalRawDataStreamPosition, SeekOrigin.Begin);
        }
    }
}
复制代码

WavAudioSink.cs       (音频信息类)

View Code

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace VoiceControl
{
    public class WavAudioSink:AudioSink
    {
        // 设置需要记录的内存流
        private MemoryStream _stream;
        // 设置当前的音频格式
        private AudioFormat _format;

        public Stream BackingStream
        {
            get { return _stream; }
        }

        public AudioFormat CurrentFormat
        {
            get { return _format; }
        }

        protected override void OnCaptureStarted()
        {
            _stream = new MemoryStream(1024);
        }

        protected override void OnCaptureStopped()
        {

        }

        protected override void OnFormatChange(AudioFormat audioFormat)
        {
            if (audioFormat.WaveFormat != WaveFormatType.Pcm)
                throw new InvalidOperationException("WavAudioSink只支持PCM音频格式");

            _format = audioFormat;
        }

        protected override void OnSamples(long sampleTime, long sampleDuration,
            byte[] sampleData)
        {
            // 新的音频数据到达,将它们写入流
            _stream.Write(sampleData, 0, sampleData.Length);
        }
    }
}

  


复制代码
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace VoiceControl
{
    public class WavAudioSink:AudioSink
    {
        // 设置需要记录的内存流
        private MemoryStream _stream;
        // 设置当前的音频格式
        private AudioFormat _format;

        public Stream BackingStream
        {
            get { return _stream; }
        }

        public AudioFormat CurrentFormat
        {
            get { return _format; }
        }

        protected override void OnCaptureStarted()
        {
            _stream = new MemoryStream(1024);
        }

        protected override void OnCaptureStopped()
        {

        }

        protected override void OnFormatChange(AudioFormat audioFormat)
        {
            if (audioFormat.WaveFormat != WaveFormatType.Pcm)
                throw new InvalidOperationException("WavAudioSink只支持PCM音频格式");

            _format = audioFormat;
        }

        protected override void OnSamples(long sampleTime, long sampleDuration,
            byte[] sampleData)
        {
            // 新的音频数据到达,将它们写入流
            _stream.Write(sampleData, 0, sampleData.Length);
        }
    }
}
复制代码

AudioUpload.asmx   

View Code

[WebMethod]
        public int UploadMyAudio(byte [] fileByte,string fileName)
        {
            string audioFilePath = HttpContext.Current.Server.MapPath("~/Files/AudioRecorder");
            string filePath = audioFilePath + "/" + fileName;
            FileStream stream = new FileStream(filePath, FileMode.CreateNew);
            stream.Write(fileByte, 0, fileByte.Length);
            stream.Close();
            return fileByte.Length;
        }

  


复制代码
[WebMethod]
        public int UploadMyAudio(byte [] fileByte,string fileName)
        {
            string audioFilePath = HttpContext.Current.Server.MapPath("~/Files/AudioRecorder");
            string filePath = audioFilePath + "/" + fileName;
            FileStream stream = new FileStream(filePath, FileMode.CreateNew);
            stream.Write(fileByte, 0, fileByte.Length);
            stream.Close();
            return fileByte.Length;
        }
复制代码

web.Config配置文件:

View Code

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
      <httpRuntime executionTimeout="648000" maxRequestLength="100000000" ></httpRuntime>
    </system.web>
    <system.webServer>
      <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
</configuration>

  


复制代码
<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
      <httpRuntime executionTimeout="648000" maxRequestLength="100000000" ></httpRuntime>
    </system.web>
    <system.webServer>
      <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
</configuration>
复制代码

 程序缺点:

     首先是必须通过Isolated Storage对象在客户端拓展独立存储空间(当然大小可以根据实际需要自定义),因为我还没有找到一个更好的办法将WAV文件存储到本地,或者说满足SavePcmToWav方法的第二个参数;其次,最终得到的WAV文件大小实在不敢恭维,本人做了一个测试,30秒的录音最终可以得到一个35M左右的WAV文件,提醒,是WAV文件,然后还要上传到服务器,这些都是相当恐怖的。同样的,Win7再带的录音功能35秒的录音得到的WMA文件,提醒,是WMA文件,却不到1M大小。最后,在SL程序中,不能应用非SL运行库生成的其他DLL,导致无法借助外部程序压缩WAV文件或者优化本程序。

程序待优化部分:

1.有木有其他解决方案,即不用Silverlight同样可以完成类似功能;

2.能不能不需要先将WAV文件保存到独立存储空间(既保存到本地),然后将该文件Stream通过WebService传到服务器,或者直接将内存流在Web直接转换成音频文件;

3.在转换内存流的步骤中,可不可以将MemoryStream保存为如MP3,WMA或者其他格式的音频文件,来压缩音频文件大小。

4.求一个更好的文件上传方法。

  源码下载

转自:http://www.cnblogs.com/doyuanbest/archive/2012/12/26/2834325.html