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


    •前言

      今天遇到一个技术上的难题,如何通过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

  • 相关阅读:
    linux -- 部署java服务器(3) linux安装redis
    linux 安装php8
    linux mysql查看日志
    linux mysql常用的命令
    perl heredoc
    perl数值进制
    提问的智慧
    How to ask question the smart way
    PERL命令行
    图灵/异步图书
  • 原文地址:https://www.cnblogs.com/suzh/p/2961685.html
Copyright © 2020-2023  润新知