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

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

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

22 комментария

Еще одна потрясающая возможность 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, которые позволяют получить доступ к видео и аудио как к набору байтов. Оба класса абстрактные, поэтому от разработчика потребуется определить собственные классы и несколько методов.

Реклама

Written by Sergiy Baydachnyy

14.01.2010 в 15:01

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

Tagged with

комментария 22

Subscribe to comments with RSS.

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

  2. You really make it seem so easy with your presentation but I find this topic
    to be really something that I think I would never understand.
    It seems too complicated and very broad for me.

    I am looking forward for your next post, I’ll try to get the hang of it!

    edit google plus age

    06.06.2014 at 14:52

  3. I would like to thank you for the efforts you’ve put in penning this blog.
    I am hoping to see the same high-grade content by you later on as
    well. In truth, your creative writing abilities has motivated me to get my own site now
    😉

    Maria

    16.06.2014 at 12:09

  4. Excellent, what a website it is! This web site presents helpful data to us, keep
    it up.

  5. Yes bookmaking this site wasn’t an undesirable decision seeing
    that it is an excellent post!

    Stanton

    18.06.2014 at 06:35

  6. Niice post. I was checking constantly this blog and I am inspired!
    Very useful info specifically the final phase 🙂 I care for such info
    a lot. I used to be seeking this particular info for a very long time.
    Thank you and good luck.

  7. Hi there, just became aware of your blog through Google,
    and found that it is really informative. I’m gonna watch out for brussels.
    I’ll appreciate if you continue this inn future. Numerous people will be benefited
    ftom your writing. Cheers!

  8. This paragraph wll help the internet people for creating new blog or even a weblog from sstart tto
    end.

    Dann

    01.07.2014 at 18:08

  9. I’m not that much of a internet reader to tell the truth however your site is great,
    continue the good work! I’ll proceed and bookmark your website to come back later.
    The best.

  10. Thank you for any other informative blog. Where else could I get that
    type of information written in such an ideal method?
    I’ve a project that I am just now operating
    on, and I have been on the look out for such info.

  11. It is perfect time to make a few plans for the future
    and it’s time to be happy. I have learn this post and if I may I want to recommend you some attention-grabbing things or advice.
    Perhaps you could write next articles regarding this article.
    I wish to read even more things approximately it!

  12. Hey there! I understand this is kind of off-topic but I had to ask.
    Does running a well-established blog such as yours take a lot of
    work? I am brand new to operating a blog but I do write in my diary daily.
    I’d like to start a blog so I can share my personal experience and feelings online.
    Please let me know if you have any kind of recommendations or tips for brand new aspiring bloggers.
    Thankyou!

    Rosaline

    14.07.2014 at 20:53

  13. If some one wishes to be updated with newest technologies after that he must be pay
    a quick visit this site and be up to date everyday.

  14. This is a topic whiсh iѕ neaг to my heart… Many thanks!
    Whеre are yօur contact details tɦough?

  15. Hello all, here every person is sharing these kinds
    of experience, so it’s nice to read this webpage, and I used to
    pay a visit this website all the time.

  16. It’s going to be end of mine day, except before finish I am reading this fantastic paragraph to improve my
    knowledge.

  17. Excellent, ԝhat a blog it iѕ! Thiss blog peesents useful fɑcts to us, keeр it up.

    Isabella

    22.08.2014 at 04:25

  18. Link exchange is nothing else but it is only placing the other person’s website
    link on your page at appropriate place and other person will also do similar in favor of
    you.

    vera john på nett

    06.09.2014 at 07:33

  19. The plugins are automatically generated by the SOOMLA store designer based
    on your selected theme and customization of the look&feel.
    Wo — W may be a fantasy game with steampunk elements,
    but the game offers little that distinguishes it from its
    competitors. These range from classic modes like Team Deathmatch to objective based modes like Rush and Conquest.

    game servers

    09.09.2014 at 09:39

  20. The state owned telecommunications company, Telkom, possess the monopoly
    and squash all opposition. This makes internet advertising extremely cost-effective.
    If you need to narrow your focus, you can start your individual forum that’s
    based on your personal particular division of interest.

    Homenet Opinie

    19.11.2014 at 05:58


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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: