您的位置:首页 > 其它

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

2013-03-15 16:30 363 查看
•前言

  今天遇到一个技术上的难题,如何通过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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: