Список AVCaptureDevice не обновляется после подключения/отключения USB-камеры

У меня есть простая программа C или Objective-C, которая печатает все подключенные видеоустройства в MacOS с использованием фреймворка AVFoundation. Когда я отключаю или подключаю новое устройство видеозахвата, список не обновляется, пока я не остановлю программу и не запущу ее снова.

Мой код выглядит следующим образом:

#import <AVFoundation/AVFoundation.h>
#include <stdio.h>

void print_devices() {
  NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
  for (AVCaptureDevice *device in devices) {
    const char *name = [[device localizedName] UTF8String];
    fprintf(stderr, "Device: %s\n", name);
  }
}

int main() {
  print_devices();

  sleep(10);
  // I connect or disconnect new capture device here via USB

  print_devices();
  // second print_devices(); displays exact same devices
  // as first call to this function.

  return 0;
}

Моя реальная программа выглядит немного иначе, и я вызываю код из программы Go, но это минимальный код воспроизведения, чтобы увидеть, в чем проблема. Я всегда печатаю одни и те же устройства, пока не остановлю программу и не запущу ее снова, тогда новые устройства будут обнаружены правильно.

Где подвох или что мне здесь не хватает?


person Jan Kuri    schedule 13.04.2018    source источник


Ответы (1)


Вам нужно запустить цикл событий.

Скорее всего, AVFoundation обновляет список своих устройств только в ответ на события. Вы вызываете sleep() в этом приложении. Во время сна приложение не получает уведомлений. Таким образом, массив устройств будет одинаковым до и после sleep().

Если вы используете фреймворки Apple Foundation/AppKit/UIKit, вам нужно написать программу в стиле Apple. Это означает использование цикла выполнения и таймеров вместо sleep();

person TyR    schedule 13.04.2018
comment
Спасибо за быстрый ответ. Я не вызываю sleep() в коде моей реальной программы, я просто добавил sleep() здесь для примера, чтобы успеть подключить/отключить USB-устройство. - person Jan Kuri; 14.04.2018
comment
Наблюдаете ли вы за уведомлениями AVCaptureDeviceWasConnectedNotification и AVCaptureDeviceWasDisconnectedNotification? - person TyR; 14.04.2018
comment
нет. на самом деле теперь я понял, что вы говорите. Как вы думаете, возможно ли вернуть свежий список устройств без реализации кода в стиле Apple и подписаться на вышеупомянутых наблюдателей? У меня есть/нужна только одна функция, которая возвращает мне имя устройства и индекс устройства, поэтому я могу отобразить его в веб-приложении, а затем использовать с ffmpeg. Если это возможно, я бы действительно не стал усложнять эту функцию. Спасибо за помощь. - person Jan Kuri; 14.04.2018
comment
Вам нужен цикл выполнения для этого, я почти уверен. Это не будет слишком болезненно реализовать, и архитектурно намного чище, чем опрос. Вот хорошая отправная точка: stackoverflow.com/questions/2154600/ - person TyR; 14.04.2018
comment
Я полный нуб в macos dev или яблочных фреймворках, тоже хотел остаться таким, но похоже, что так не пойдет :) Понятно, это хорошая отправная точка, которая может довольно быстро привести меня к конечному результату. Спасибо! Пометка вашего ответа как принятого. - person Jan Kuri; 14.04.2018