Блог Сергея Байдачного

Мой блог о технологиях

Введение в SilverLight 4: Работа с камерой и микрофоном

с 2 комментариями

Еще одна потрясающая возможность SilverLight 4, это поддержка камеры и микрофона. Чтобы показать эти возможности в действии, рассмотрим небольшой пример. Для этого создадим новый SilverLight-проект и реализуем следующий интерфейс:

<UserControl x:Class="WebCam_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel x:Name="LayoutRoot" Background="White" 
        Loaded="LayoutRoot_Loaded">
        <Rectangle Width="400" Height="300" Fill="Gray" 
            Name="videoContainer">
        </Rectangle>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <StackPanel>
                <TextBlock Text="Video Devices" Margin="5"></TextBlock>
                <ListBox Height="30" Name="videoBox">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock 
                             Text="{Binding FriendlyName}">
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
            <StackPanel>
                <TextBlock Text="Audio Devices" Margin="5"></TextBlock>
                <ListBox Height="30" Name="audioBox">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock 
                             Text="{Binding FriendlyName}">
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Start" Width="100" Height="30" 
                Click="Start_Click" Margin="5"></Button>
            <Button Content="Stop" Width="100" Height="30" 
                Click="Stop_Click" Margin="5"></Button>
            <Button Content="Capture" Width="100" Height="30" 
                Margin="5" Click="Capture_Click"></Button>
        </StackPanel>
        <ScrollViewer Width="500" Height="200" 
            HorizontalScrollBarVisibility="Visible" 
            VerticalScrollBarVisibility="Hidden">
            <ItemsControl Name="imageContainer">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding}" 
                         Stretch="UniformToFill" 
                         Height="150" Margin="5">
                        </Image>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" 
                         VerticalAlignment="Center" 
                         HorizontalAlignment="Center">
                        </StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </StackPanel>
</UserControl>

Предложенный интерфейс будет выглядеть так, как на рисунке ниже:

image

Элемент Rectangle мы будем использовать для отображения видео, два элемента ListBox – для выдачи списка доступных устройств, а ScrollView элемент – для отображения изображений, захваченных во время отображения видео.

Итак, получить аудио и видео потоки можно с помощью класса CaptureSource. Структура этого класса достаточно простая, так, тут можно выделить два всего два основных метода и три основных свойства:

· Start – инициирует доступ объекта типа CaptureSource к аудио и видео потокам;

· Stop – закрывает доступ к видео и аудио потокам;

· VideoCaptureDevice – задает устройство для получения видео потока;

· AudioCaptureDevice – задает устройство для получения аудио потока;

· State – определяет состояние объекта типа CaptureSource: Started – запушен и получает потоки; Stopped – остановлен; Failed – проблемы с подключением.

Таким образом, чтобы приступить к работе с видео и аудио, необходимо создать объект типа CaptureSource:

private CaptureSource _source = new CaptureSource();

Прежде, чем запустить работу с потоками, необходимо выбрать и установить устройства. Для этих целей используется класс CaptureDeviceConfiguration, содержащий несколько статических методов:

· GetAvailableAudioCaptureDevices – возвращает список доступных аудио устройств (как набор объектов типа AudioCaptureDevice);

· GetAvailableVideoCaptureDevices – возвращает список доступных видео устройств (как набор объектов типа VideoCaptureDevice);

· GetDefaultAudioCaptureDevice – возвращает устройство по умолчанию;

· GetDefaultVideoCaptureDevice – возвращает устройство по умолчанию.

Таким образом, чтобы получить список всех устройств, реализуем код:

audioBox.ItemsSource = 
  CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();
videoBox.ItemsSource = 
  CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

В свою очередь, код, устанавливающий выбранные устройства объекту типа CaptureSource, во время запуска работы с потоками, будет выглядеть следующим образом:

_source.VideoCaptureDevice = (VideoCaptureDevice)videoBox.SelectedItem;
_source.AudioCaptureDevice = (AudioCaptureDevice)audioBox.SelectedItem;

Теперь наша задача использовать CaptureSource для вывода видео на экран. Для этого мы и будем использовать элемент Rectangle и объект типа VideoBrush для его заливки:

VideoBrush vBrush = new VideoBrush();
vBrush.SetSource(_source);
videoContainer.Fill = vBrush;

Создав объект типа CaptureSource и установивив все необходимые параметры, можно приступать к вызову метода Start. Но, прежде чем сделать это, необходимо проверить, имеет ли приложение права на доступ к устройствам, а если не имеет, то права необходимо запросить у пользователя. Проверить наличие прав и запросить доступ можно с помощью уже знакомого класса CaptureDeviceConfiguration. Для этого используется свойство AllowedDeviceAccess и метод RequestDeviceAccess соответственно. Таким образом, код, выполняющий запуск объекта типа CaptureSource, должен выглядеть следующим образом:

    if (CaptureDeviceConfiguration.AllowedDeviceAccess 
       || CaptureDeviceConfiguration.RequestDeviceAccess())
    {
        _source.Start();
    }

Выше были перечисленны основные действия, которые необходимо проделать для отображения видео в SilverLight-приложении. Естественно к данному коду необходимо добавить различные проверки и реализовать механизм захвата изображения. Детально я это расписывать не буду, а прото приведу готовый код:

private CaptureSource _source = new CaptureSource();
private ObservableCollection<WriteableBitmap> _images = 
    new ObservableCollection<WriteableBitmap>();
 
public MainPage()
{
    InitializeComponent();
}
 
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    audioBox.ItemsSource = 
      CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();
    videoBox.ItemsSource = 
      CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
 
    if ((videoBox.Items.Count > 0) && (audioBox.Items.Count > 0))
    {
        videoBox.SelectedIndex = 0;
        audioBox.SelectedIndex = 0;
    }
 
    imageContainer.ItemsSource = _images;
}
 
private void Stop_Click(object sender, RoutedEventArgs e)
{
    _source.Stop();
}
 
private void Start_Click(object sender, RoutedEventArgs e)
{
    if ((videoBox.Items.Count==0)||(audioBox.Items.Count==0))
    {
        MessageBox.Show("Audio or Video device is not available");
        return;
    }
 
    _source.VideoCaptureDevice = (VideoCaptureDevice)videoBox.SelectedItem;
    _source.AudioCaptureDevice = (AudioCaptureDevice)audioBox.SelectedItem;
 
    VideoBrush vBrush = new VideoBrush();
    vBrush.SetSource(_source);
 
    videoContainer.Fill = vBrush;
 
    if (CaptureDeviceConfiguration.AllowedDeviceAccess 
       || CaptureDeviceConfiguration.RequestDeviceAccess())
    {
        _source.Start();
    }
}
 
private void Capture_Click(object sender, RoutedEventArgs e)
{
    if (_source.State == CaptureState.Started)
    {
        _source.AsyncCaptureImage(CaptureImage<WriteableBitmap>);
    }
}
 
private void CaptureImage<WriteableBitmap>(
    System.Windows.Media.Imaging.WriteableBitmap t)
{
    _images.Add(t);
}

При запуске данного приложения должно получится что-то такое (если Вы увидете свое лицо, то не расстраивайтесь, так задумано):

image

В завершении хочу отметить два класса: AudioSink и VideoSink, которые позволяют получить доступ к видео и аудио как к набору байтов. Оба класса абстрактные, поэтому от разработчика потребуется определить собственные классы и несколько методов.

Написано Sergiy Baydachnyy

14.01.2010 в 15:01

Опубликовано в SilverLight

Отмечено как

Комментариев: 2

Подписаться на комментарии по RSS.

  1. [...] Читать в моем блоге о технологиях Опубліковані Thursday, January 14, 2010 3:02 PM від Sergiy Baydachnyy [...]


Добавить комментарий

Fill in your details below or click an icon to log in:

Gravatar
Логотип WordPress.com

Пожалуйста, авторизуйтесь в WordPress.com, чтобы оставить комментарий в блоге.

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 737 other followers