Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье показано, как подключиться к одной или нескольким удаленным камерам и получить объект MediaFrameSourceGroup, позволяющий считывать кадры с каждой камеры. Дополнительные сведения о чтении кадров из источника мультимедиа см. в разделе "Обработка кадров мультимедиа" с помощью MediaFrameReader. Дополнительные сведения о связывании с устройствами см. в разделе "Пары устройств".
Note
Функции, рассмотренные в этой статье, доступны начиная с Windows 10 версии 1903.
Создание класса DeviceWatcher для просмотра доступных удаленных камер
Класс DeviceWatcher отслеживает устройства, доступные вашему приложению, и уведомляет приложение о добавлении или удалении устройств. Получите экземпляр DeviceWatcher , вызвав DeviceInformation.CreateWatcher, передав строку расширенного синтаксиса запросов (AQS), которая определяет тип устройств, которые необходимо отслеживать. Строка AQS, указывающая устройства сетевой камеры, приведена ниже.
@"System.Devices.InterfaceClassGuid:=""{B8238652-B500-41EB-B4F3-4234F7F5AE99}"" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True"
Note
Вспомогательный метод MediaFrameSourceGroup.GetDeviceSelector возвращает строку AQS, которая будет отслеживать локально подключенные и удаленные сетевые камеры. Чтобы отслеживать только сетевые камеры, следует использовать строку AQS, показанную выше.
Когда вы запускаете возвращаемый DeviceWatcher вызовом метода Start, будет возникать событие Added для каждой сетевой камеры, которая в данный момент доступна. Пока вы не остановите наблюдатель, вызвав Stop, событие Added будет вызываться, когда становятся доступными новые сетевые камеры, а событие Removed — когда устройство камеры становится недоступным.
Аргументы события, передаваемые в обработчики событий Added и Removed, представляют собой объекты DeviceInformation и DeviceInformationUpdate соответственно. У каждого из этих объектов есть свойство Id , которое является идентификатором сетевой камеры, для которой было запущено событие. Передайте этот идентификатор в метод MediaFrameSourceGroup.FromIdAsync , чтобы получить объект MediaFrameSourceGroup , который можно использовать для извлечения кадров из камеры.
Вспомогательный класс для сопряжения удалённой камеры
В следующем примере показан вспомогательный класс, использующий DeviceWatcher для создания и обновления объектов ObservableCollection объектов MediaFrameSourceGroup для поддержки привязки данных к списку камер. Типичные приложения упаковывают MediaFrameSourceGroup в пользовательский класс модели. Обратите внимание, что вспомогательный класс хранит ссылку на DispatcherQueue приложения и обновляет список камер в потоке пользовательского интерфейса.
Кроме того, в этом примере выполняется событие DeviceWatcher.Updated в дополнение к событиям "Добавлено и удалено ". В обработчике Updated связанное устройство удалённой камеры удаляется из коллекции, а затем снова добавляется в неё.
class RemoteCameraPairingHelper : IDisposable
{
private DispatcherQueue _dispatcherQueue;
private DeviceWatcher _watcher;
private ObservableCollection<MediaFrameSourceGroup> _remoteCameraCollection;
public RemoteCameraPairingHelper(DispatcherQueue uiDispatcherQueue)
{
_dispatcherQueue = uiDispatcherQueue;
_remoteCameraCollection = new ObservableCollection<MediaFrameSourceGroup>();
var remoteCameraAqs = @"System.Devices.InterfaceClassGuid:=""{B8238652-B500-41EB-B4F3-4234F7F5AE99}"" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";
_watcher = DeviceInformation.CreateWatcher(remoteCameraAqs);
_watcher.Added += Watcher_Added;
_watcher.Removed += Watcher_Removed;
_watcher.Updated += Watcher_Updated;
_watcher.Start();
}
public void Dispose()
{
_watcher.Stop();
_watcher.Updated -= Watcher_Updated;
_watcher.Removed -= Watcher_Removed;
_watcher.Added -= Watcher_Added;
}
public IReadOnlyList<MediaFrameSourceGroup> FrameSourceGroups
{
get { return _remoteCameraCollection; }
}
private async void Watcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
{
await RemoveDevice(args.Id);
await AddDeviceAsync(args.Id);
}
private async void Watcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
{
await RemoveDevice(args.Id);
}
private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
{
await AddDeviceAsync(args.Id);
}
private async Task AddDeviceAsync(string id)
{
var group = await MediaFrameSourceGroup.FromIdAsync(id);
if (group != null)
{
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () => {
_remoteCameraCollection.Add(group);
});
}
}
private async Task RemoveDevice(string id)
{
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
{
var existing = _remoteCameraCollection.FirstOrDefault(item => item.Id == id);
if (existing != null)
{
_remoteCameraCollection.Remove(existing);
}
});
}
struct RemoteCameraPairingHelper
{
RemoteCameraPairingHelper(DispatcherQueue uiDispatcher) :
m_dispatcherQueue(uiDispatcher)
{
m_remoteCameraCollection = winrt::single_threaded_observable_vector<MediaFrameSourceGroup>();
auto remoteCameraAqs =
LR"(System.Devices.InterfaceClassGuid:="{B8238652-B500-41EB-B4F3-4234F7F5AE99}")"
LR"(AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True)";
m_watcher = DeviceInformation::CreateWatcher(remoteCameraAqs, nullptr);
m_watcherAddedAutoRevoker = m_watcher.Added(winrt::auto_revoke, { this, &RemoteCameraPairingHelper::Watcher_Added });
m_watcherRemovedAutoRevoker = m_watcher.Removed(winrt::auto_revoke, { this, &RemoteCameraPairingHelper::Watcher_Removed });
m_watcherUpdatedAutoRevoker = m_watcher.Updated(winrt::auto_revoke, { this, &RemoteCameraPairingHelper::Watcher_Updated });
m_watcher.Start();
}
~RemoteCameraPairingHelper()
{
m_watcher.Stop();
}
IObservableVector<MediaFrameSourceGroup> FrameSourceGroups()
{
return m_remoteCameraCollection;
}
winrt::fire_and_forget Watcher_Added(DeviceWatcher /* sender */, DeviceInformation args)
{
co_await AddDeviceAsync(args.Id());
}
winrt::fire_and_forget Watcher_Removed(DeviceWatcher /* sender */, DeviceInformationUpdate args)
{
co_await RemoveDevice(args.Id());
}
winrt::fire_and_forget Watcher_Updated(DeviceWatcher /* sender */, DeviceInformationUpdate args)
{
co_await RemoveDevice(args.Id());
co_await AddDeviceAsync(args.Id());
}
Windows::Foundation::IAsyncAction AddDeviceAsync(winrt::hstring id)
{
auto group = co_await MediaFrameSourceGroup::FromIdAsync(id);
if (group)
{
//co_await m_dispatcherQueue;
co_await wil::resume_foreground(m_dispatcherQueue);
m_remoteCameraCollection.Append(group);
}
}
Windows::Foundation::IAsyncAction RemoveDevice(winrt::hstring id)
{
//co_await m_dispatcherQueue;
co_await wil::resume_foreground(m_dispatcherQueue);
uint32_t ix{ 0 };
for (auto const&& item : m_remoteCameraCollection)
{
if (item.Id() == id)
{
m_remoteCameraCollection.RemoveAt(ix);
break;
}
++ix;
}
}
private:
DispatcherQueue m_dispatcherQueue{ nullptr };
DeviceWatcher m_watcher{ nullptr };
IObservableVector<MediaFrameSourceGroup> m_remoteCameraCollection;
DeviceWatcher::Added_revoker m_watcherAddedAutoRevoker;
DeviceWatcher::Removed_revoker m_watcherRemovedAutoRevoker;
DeviceWatcher::Updated_revoker m_watcherUpdatedAutoRevoker;
};
Связанные темы
Windows developer