微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

稳扎稳打Silverlight(49) - 4.0媒体之摄像头和麦克风

  [源码下载]

稳扎稳打Silverlight(49) - 4.0媒体之摄像头和麦克风

作者: webabcd
介绍
Silverlight 4.0 媒体方面的增强:

在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
1、演示如何捕获摄像头
MemoryStreamVideosink.cs

代码
/*
 * Videosink - 用于捕获视频信息。抽象类,其有一个 CaptureSource 类型的属性
 
*/

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  Silverlight40.WebcamMic
{
    
public   class  MemoryStreamVideosink : Videosink
    {
        
public  VideoFormat VideoFormat {  get private   set ; }
        
public  MemoryStream MemoryStream {  get private   set ; }

        
//  当视频设备开始捕获视频数据时所调用方法
         protected   override   void  OnCaptureStarted()
        {
            MemoryStream 
=   new  MemoryStream();
        }

        
//  当视频设备停止捕获视频数据时所调用方法
         protected   override   void  OnCaptureStopped()
        {

        }

        
///   <summary>
        
///  当视频设备报告视频格式更改时所调用方法
        
///  当视频设备开始捕获视频数据时会调用一次 OnFormatChange,此时便可以确定当前的视频格式
        
///   </summary>
        
///   <param name="videoFormat"> 新的视频格式 </param>
         protected   override   void  OnFormatChange(VideoFormat videoFormat)
        {
            VideoFormat 
=  videoFormat;
        }

        
///   <summary>
        
///  当视频设备捕获了一个完整的视频采样时所调用方法
        
///   </summary>
        
///   <param name="sampleTime"> 当前采样被捕获时的时间。单位:100纳秒 </param>
        
///   <param name="frameDuration"> 当前采样的时长。单位:100纳秒 </param>
        
///   <param name="sampleData"> 当前采样的视频数据的字节流 </param>
         protected   override   void  OnSample( long  sampleTime,  long  frameDuration,  byte [] sampleData)
        {
            MemoryStream.Write(sampleData, 
0 , sampleData.Length);
        }
    }
}

Webcam.xaml

代码
< navigation:Page  x:Class ="Silverlight40.WebcamMic.Webcam"  
           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"
           xmlns:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           Title
="Webcam Page" >
    
< Grid  x:Name ="LayoutRoot" >
        
< StackPanel  HorizontalAlignment ="Left" >

            
< TextBlock  Text ="可用的视频捕获设备列表"   />
            
< ListBox  Name ="videoSources" >
                
< ListBox.ItemTemplate >
                    
< DataTemplate >
                        
< TextBlock  Text =" {Binding FriendlyName} "   />
                    
</ DataTemplate >
                
</ ListBox.ItemTemplate >
            
</ ListBox >

            
<!-- 显示 CaptureSource 中的视频 -->
            
< Border  Width ="320"  Height ="240"  CornerRadius ="10"  BorderThickness ="1"  BorderB@R_404_6178@ ="Blue" >
                
< Rectangle  Name ="webcamCapture"  Fill ="Black" />
            
</ Border >

            
< Button  Name ="btnStartCapture"  Content ="开始捕获"  Click ="btnStartCapture_Click"   />
            
< Button  Name ="btnStopCapture"  Content ="停止捕获"  Click ="btnStopCapture_Click"   />
            
< Button  Name ="btnTakeSnapshot"  Content ="截图"  Click ="btnTakeSnapshot_Click"   />

            
<!-- 显示截图结果 -->
            
< ScrollViewer  Width ="320"  VerticalScrollBarVisibility ="Hidden"  HorizontalScrollBarVisibility ="Auto" >
                
< ItemsControl  Name ="snapshots" >
                    
< ItemsControl.ItemTemplate >
                        
< DataTemplate >
                            
< Image  Source =" {Binding} "  Margin ="3"  Stretch ="Fill"  Height ="50"   />
                        
</ DataTemplate >
                    
</ ItemsControl.ItemTemplate >
                    
< ItemsControl.ItemsPanel >
                        
< ItemsPanelTemplate >
                            
< StackPanel  Orientation ="Horizontal"  HorizontalAlignment ="Center"  VerticalAlignment ="Center"   />
                        
</ ItemsPanelTemplate >
                    
</ ItemsControl.ItemsPanel >
                
</ ItemsControl >
            
</ ScrollViewer >
            
        
</ StackPanel >
    
</ Grid >
</ navigation:Page >

Webcam.xaml.cs

代码
/*
 * 演示 Silverlight 4.0 对视频捕获设备的支持
 * CaptureDeviceConfiguration - 视频捕获设备及音频捕获设备的相关信息
 *     GetAvailableVideoCaptureDevices() - 返回可用的视频捕获设备的集合。VideoCaptureDevice 类型的集合
 *     GetDefaultVideoCaptureDevice() - 返回认的视频捕获设备。VideoCaptureDevice 类型
 *     RequestDeviceAccess() - 请求访问所有可能的视频捕获设备和音频捕获设备。弹出确认对话框后(被信任的应用程序不会弹出此对话框),用户允许则返回 true
 *     AllowedDeviceAccess - 用户以前是否允许了可以访问视频捕获设备和音频捕获设备(当用户以前允许过,并且允许的时候选择了“记住我的答案”,则返回 true)
 * 
 * CaptureSource - 捕获源,用于提供捕获视频和音频的一些相关方法
 *     Start() - 开始捕获 
 *     Stop() - 停止捕获
 *     VideoCaptureDevice - 指定用于捕获视频的设备, VideoCaptureDevice 类型
 *     State - 捕获状态 [System.Windows.Media.CaptureState 枚举(Stopped, Started, Failed)]
 *     CaptureImageAsync() - 启动一个异步图像捕获请求
 *     CaptureImageCompleted - 当异步图像捕获请求完成时所触发的事件
 *     CaptureFailed - 捕获失败时所触发的事件
 * 
 * VideoCaptureDevice - 视频捕获设备的相关信息
 *     FriendlyName - 视频捕获设备的名称
 *     IsDefaultDevice - 是否是认的视频捕获设备
 *     SupportedFormats - 此视频捕获设备所支持的视频格式的集合。VideoFormat 类型的集合
 *     DesiredFormat - 需要视频捕获设备使用的视频格式。VideoFormat 类型
 * 
 * VideoFormat - 捕获视频的视频格式信息
 *     PixelWidth - 视频区域的宽度,以像素为单位
 *     PixelHeight - 视频区域的高度,以像素为单位
 *     PixelFormat - 视频编码格式 [System.Windows.Media.PixelFormatType 枚举],目前仅支持 PixelFormatType.Format32bppArgb
 *     FramesPerSecond - 视频的每秒帧数
 *     Stride - 图像的行的宽度,以字节为单位,如果是负数则表示图像倒置
 * 
 * VideoB@R_404[email protected](CaptureSource) - 指定一个视频捕获源做为 VideoB@R_404_6178@ 的源
 
*/

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.Windows.Navigation;

using  System.Collections.ObjectModel;
using  System.Windows.Media.Imaging;
using  System.IO;

namespace  Silverlight40.WebcamMic
{
    
public   partial   class  Webcam : Page
    {
        
private  CaptureSource _captureSource;
        
private  MemoryStreamVideosink _videosink;
        
private  ObservableCollection < WriteableBitmap >  _images  =   new  ObservableCollection < WriteableBitmap > ();

        
public  Webcam()
        {
            InitializeComponent();
        }

        
protected   override   void  OnNavigatedTo(NavigationEventArgs e)
        {
            
//  可用的视频捕获设备列表
            videoSources.ItemsSource  =  CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

            _captureSource 
=   new  CaptureSource();
            _captureSource.VideoCaptureDevice 
=  CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

            
//  截图完成
            _captureSource.CaptureImageCompleted  +=  ((s, args)  =>  { _images.Add(args.Result); });
            
//  视频截图列表
            snapshots.ItemsSource  =  _images;

            
//  Videosink 用于处理捕获视频信息的相关逻辑
            _videosin =   new  MemoryStreamVideosink();
            _videosink.CaptureSource 
=  _captureSource;
        }


        
private   void  btnStartCapture_Click( object  sender, RoutedEventArgs e)
        {
            
//  将视频捕获框填充到指定的 Rectangle 中
            VideoB@R_404_6178@ videoB@R_404_6178@  =   new  VideoB@R_404_6178@();
            videoB@R_404[email protected](_captureSource);
            webcamCapture.Fill 
=  videoB@R_404_6178@;

            
//  如果允许启用摄像头,则开始捕获
             if  (CaptureDeviceConfiguration.AllowedDeviceAccess  ||  CaptureDeviceConfiguration.RequestDeviceAccess())
                _captureSource.Start();
        }

        
private   void  btnStopCapture_Click( object  sender, RoutedEventArgs e)
        {
            _captureSource.Stop();
        }

        
private   void  btnTakeSnapshot_Click( object  sender, RoutedEventArgs e)
        {
            _captureSource.CaptureImageAsync();
        }
    }
}

2、演示如何捕获麦克风
MemoryStreamAudioSink.cs

代码
/*
 * AudioSink - 用于捕获音频信息。抽象类,其有一个 CaptureSource 类型的属性
 
*/

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  Silverlight40.WebcamMic
{
    
public   class  MemoryStreamAudioSink : AudioSink
    {
        
public  AudioFormat AudioFormat {  get private   set ; }
        
public  MemoryStream MemoryStream {  get private   set ; }

        
//  当音频设备开始捕获音频数据时所调用方法
         protected   override   void  OnCaptureStarted()
        {
            MemoryStream 
=   new  MemoryStream();
        }

        
//  当音频设备停止捕获音频数据时所调用方法
         protected   override   void  OnCaptureStopped()
        {

        }

        
///   <summary>
        
///  当音频设备报告音频格式更改时所调用方法
        
///  当音频设备开始捕获音频数据时会调用一次 OnFormatChange,此时便可以确定当前的音频格式
        
///   </summary>
        
///   <param name="audioFormat"> 新的音频格式 </param>
         protected   override   void  OnFormatChange(AudioFormat audioFormat)
        {
            AudioFormat 
=  audioFormat;
        }

        
///   <summary>
        
///  当音频设备捕获了一个完整的音频采样时所调用方法
        
///   </summary>
        
///   <param name="sampleTime"> 当前采样被捕获时的时间。单位:100纳秒 </param>
        
///   <param name="sampleDuration"> 当前采样的时长。单位:100纳秒 </param>
        
///   <param name="sampleData"> 当前采样的音频数据的字节流 </param>
         protected   override   void  OnSamples( long  sampleTime,  long  sampleDuration,">WavFileHelper.cs

代码
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  Silverlight40.WebcamMic
{
    
public   static   class  WavFileHelper
    {
        
//  获取 PCM 格式的音频头的字节数组
         public   static   byte [] GetWavFileHeader( long  audioByteLength, AudioFormat audioFormat)
        {
            MemoryStream stream 
=   new  MemoryStream( 44 );

            
//  “RIFF”
            stream.Write( new   byte [] {  0x52 0x49 0x46 0x46  },  4 );

            
//  文件长度 = 音频数据长度 + 44个字节的header长度 - 8个字节(上面的4个字节和这里的4个字节)
            stream.Write(BitConverter.GetBytes((UInt32)(audioByteLength  +   44   -   8 )),  4 );

            
//  “WAVE”
            stream.Write( new   byte [] {  0x57 0x41 0x56 0x45  },  4 );

            
//  “fmt ”
            stream.Write( new   byte [] {  0x66 0x6D 0x74 0x20  },  4 );

            
//  对于 PCM 来说,这里的值为 16
            stream.Write(BitConverter.GetBytes((UInt32) 16 ),  4 );

            
//  “1”代表未压缩
            stream.Write(BitConverter.GetBytes((UInt16) 1 ),  2 );

            
//  通道数:“1”代表单声道;“2”代表双声道
            stream.Write(BitConverter.GetBytes((UInt16)audioFormat.Channels),  2 );

            
//  采样率(采样频率),即每秒样本数
            stream.Write(BitConverter.GetBytes((UInt32)audioFormat.SamplesPerSecond),  4 );

            
//  比特率,即每秒字节数。其值为通道数×每秒数据位数×每样本的数据位数/8(SampleRate * ChannelCount * BitsPerSample / 8)
            stream.Write(BitConverter.GetBytes((UInt32)((audioFormat.SamplesPerSecond  *  audioFormat.Channels  *  audioFormat.BitsPerSample)  /   8 )),  4 );

            
//  通道数×每样本的数据位数/8(ChannelCount * BitsPerSample / 8)
            stream.Write(BitConverter.GetBytes((UInt16)((audioFormat.Channels  *  audioFormat.BitsPerSample)  /   8 )),  2 );

            
//  采样位数(采样分辨率),即每样本的数据位数
            stream.Write(BitConverter.GetBytes((UInt16)audioFormat.BitsPerSample),  2 );

            
//  “data”
            stream.Write( new   byte [] {  0x64 0x61 0x61  },  4 );

            
//  语音数据的长度
            stream.Write(BitConverter.GetBytes((UInt32)audioByteLength),  4 );

            
return  (stream.GetBuffer());
        }
    }  
}

Mic.xaml

代码
< navigation:Page  x:Class ="Silverlight40.WebcamMic.Mic"  
           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"
           xmlns:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           Title
="Mic Page" >
    
< Grid  x:Name ="LayoutRoot" >
        
< StackPanel  HorizontalAlignment ="Left" >

            
< TextBlock  Text ="可用的音频捕获设备列表"   />
            
< ListBox  Name ="audioSources" >
                
< ListBox.ItemTemplate >
                    
< DataTemplate >
                        
< TextBlock  Text =" {Binding FriendlyName} "   />
                    
</ DataTemplate >
                
</ ListBox.ItemTemplate >
            
</ ListBox >
            
            
< TextBlock  Name ="lblMsg"   />

            
< Button  Name ="btnStartCapture"  Content ="开始捕获"  Click ="btnStartCapture_Click"   />
            
< Button  Name ="btnStopCapture"  Content ="停止捕获"  Click ="btnStopCapture_Click"   />
            
        
</ StackPanel >
    
</ Grid >
</ navigation:Page >

Mic.xaml.cs

代码
/*
 * 演示 Silverlight 4.0 对音频捕获设备的支持
 * CaptureDeviceConfiguration - 视频捕获设备及音频捕获设备的相关信息
 *     GetAvailableAudioCaptureDevices() - 返回可用的音频捕获设备的集合。AudioCaptureDevice 类型的集合
 *     GetDefaultAudioCaptureDevice() - 返回认的音频捕获设备。AudioCaptureDevice 类型
 *     RequestDeviceAccess() - 请求访问所有可能的视频捕获设备和音频捕获设备。弹出确认对话框后(被信任的应用程序不会弹出此对话框),用户允许则返回 true
 *     AllowedDeviceAccess - 用户以前是否允许了可以访问视频捕获设备和音频捕获设备(当用户以前允许过,并且允许的时候选择了“记住我的答案”,则返回 true)
 * 
 * CaptureSource - 捕获源,用于提供捕获视频和音频的一些相关方法
 *     Start() - 开始捕获 
 *     Stop() - 停止捕获
 *     AudioCaptureDevice - 指定用于捕获音频的设备, AudioCaptureDevice 类型
 *     State - 捕获状态 [System.Windows.Media.CaptureState 枚举(Stopped, Failed)]
 *     CaptureFailed - 捕获失败时所触发的事件
 * 
 * AudioCaptureDevice - 音频捕获设备的相关信息
 *     FriendlyName - 音频捕获设备的名称
 *     IsDefaultDevice - 是否是认的音频捕获设备
 *     SupportedFormats - 此音频捕获设备所支持的音频格式的集合。AudioFormat 类型的集合
 *     DesiredFormat - 需要音频捕获设备使用的音频格式。AudioFormat 类型
 *     AudioFrameSize - 音频的帧大小。单位:毫秒。认值:1000毫秒。范围:10 - 2000毫秒
 * 
 * AudioFormat - 捕获音频的音频格式信息
 *     Channels - 声道数
 *     SamplesPerSecond - 采样率(采样频率)
 *     BitsPerSample - 采样位数(采样分辨率)
 *     WaveFormat - 音频编码格式 [System.Windows.Media.WaveFormatType 枚举],目前仅支持 WaveFormatType.Pcm
 
*/

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.Windows.Navigation;

using  System.IO;

namespace  Silverlight40.WebcamMic
{
    
public   partial   class  Mic : Page
    {
        
private  CaptureSource _captureSource;
        
private  MemoryStreamAudioSink _audioSink;

        
public  Mic()
        {
            InitializeComponent();
        }

        
protected   override   void  OnNavigatedTo(NavigationEventArgs e)
        {
            
//  可用的音频捕获设备列表
            audioSources.ItemsSource  =  CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();

            _captureSource 
=   new  CaptureSource();
            _captureSource.AudioCaptureDevice 
=  CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();

            
//  AudioSink 用于处理捕获音频信息的相关逻辑
            _audioSink  =   new  MemoryStreamAudioSink();
            _audioSink.CaptureSource 
=  _captureSource;
        }

        
private   void  btnStartCapture_Click( object  sender, RoutedEventArgs e)
        {
            
//  如果允许启用麦克风,则开始捕获
             if  (CaptureDeviceConfiguration.AllowedDeviceAccess  ||  CaptureDeviceConfiguration.RequestDeviceAccess())
                _captureSource.Start();

            lblMsg.Text 
=  _captureSource.State.ToString();
        }

        
private   void  btnStopCapture_Click( object  sender, RoutedEventArgs e)
        {
            _captureSource.Stop();

            lblMsg.Text 
=  _captureSource.State.ToString();

            
if  (_audioSink.MemoryStream  ==   null )
                
return ;

            
//  弹出“另存为”对话框,保存捕获到的全部音频数据
            SaveFileDialog dialog  =   new  SaveFileDialog();
            dialog.Filter 
=   " 音频(*.wav)|*.wav " ;

            
bool ?  result  =  dialog.ShowDialog();
            
if  (result  ==   true )
            {
                
using  (Stream stream  =  dialog.OpenFile())
                {
                    
//  写入音频头
                     byte [] wavFileHeader  =  WavFileHelper.GetWavFileHeader(_audioSink.MemoryStream.Length, _audioSink.AudioFormat);
                    stream.Write(wavFileHeader, wavFileHeader.Length);

                    
byte [] buffer  =   new   byte [ 4096 ];
                    
int  read  =   0 ;

                    _audioSink.MemoryStream.Seek(
0 , SeekOrigin.Begin);

                    
//  写入音频数据
                     while  ((read  =  _audioSink.MemoryStream.Read(buffer, buffer.Length))  >   0 )
                    {
                        stream.Write(buffer, read);
                    }
                }
            }
        }
    }
}

OK
[源码下载]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐