zoukankan      html  css  js  c++  java
  • 稳扎稳打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 { getprivate set; }
            
    public MemoryStream MemoryStream { getprivate 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" BorderBrush="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 - 图像的行的宽度,以字节为单位,如果是负数则表示图像倒置
     * 
     * VideoBrush.SetSource(CaptureSource) - 指定一个视频捕获源做为 VideoBrush 的源
     
    */

    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 用于处理捕获视频信息的相关逻辑
                _videoSink = new MemoryStreamVideoSink();
                _videoSink.CaptureSource 
    = _captureSource;
            }


            
    private void btnStartCapture_Click(object sender, RoutedEventArgs e)
            {
                
    // 将视频捕获框填充到指定的 Rectangle 中
                VideoBrush videoBrush = new VideoBrush();
                videoBrush.SetSource(_captureSource);
                webcamCapture.Fill 
    = videoBrush;

                
    // 如果允许启用摄像头,则开始捕获
                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 { getprivate set; }
            
    public MemoryStream MemoryStream { getprivate 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, byte[] sampleData)
            {
                MemoryStream.Write(sampleData, 
    0, sampleData.Length);
            }
        }
    }


    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[] { 0x520x490x460x46 }, 04);

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

                
    // “WAVE”
                stream.Write(new byte[] { 0x570x410x560x45 }, 04);

                
    // “fmt ”
                stream.Write(new byte[] { 0x660x6D0x740x20 }, 04);

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

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

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

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

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

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

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

                
    // “data”
                stream.Write(new byte[] { 0x640x610x740x61 }, 04);

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

                
    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, Started, 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, 
    0, wavFileHeader.Length);

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

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

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



    OK
    [源码下载]

  • 相关阅读:
    jQuery基础教程-第8章-002Adding jQuery object methods
    jQuery基础教程-第8章-001Adding new global functions
    福利彩票-001什么是福利彩票
    Java生产者消费者问题
    Java集合
    Java线程
    JavaPersistenceWithMyBatis3笔记-第5章Configuring MyBatis in a Spring applications-001
    CentOS安装和配置Apache(httpd)
    CentOS安装和配置FTP
    PHP 常用获取路径代码
  • 原文地址:https://www.cnblogs.com/webabcd/p/1815661.html
Copyright © 2011-2022 走看看