MacOS下AVCaptureDevice列表在USB摄像头插拔后不刷新问题求助
解决AVFoundation设备列表自动刷新问题
我懂你的烦恼——每次插拔USB摄像头都得重启程序才能看到设备更新,确实挺折腾的。问题根源在于你当前的代码只是一次性获取设备列表,没有监听系统里设备连接/断开的实时事件。其实AVFoundation早就提供了专门的通知来处理这种场景,咱们只需要加上通知监听就能实现自动刷新。
修改后的完整代码
#import <AVFoundation/AVFoundation.h> #import <Foundation/Foundation.h> #include <stdio.h> void print_devices() { NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; printf("当前已连接的视频设备列表:\n"); for (AVCaptureDevice *device in devices) { const char *name = [[device localizedName] UTF8String]; const char *uniqueID = [[device uniqueID] UTF8String]; printf("- 设备名称: %s | 唯一ID: %s\n", name, uniqueID); } printf("-------------------------\n"); } // 设备连接/断开的通知回调 void deviceChangedNotification(__unused NSNotification *notification) { print_devices(); } int main(int argc, const char * argv[]) { @autoreleasepool { // 注册设备连接通知 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserverForName:AVCaptureDeviceWasConnectedNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:deviceChangedNotification]; // 注册设备断开通知 [center addObserverForName:AVCaptureDeviceWasDisconnectedNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:deviceChangedNotification]; // 先打印一次初始设备列表 print_devices(); // 保持程序运行(控制台程序需要RunLoop来等待通知触发) [[NSRunLoop currentRunLoop] run]; // 若程序有明确退出逻辑,记得移除通知观察者避免内存泄漏 // [center removeObserver:observer]; } return 0; }
关键细节说明
- 通知监听核心:通过
AVCaptureDeviceWasConnectedNotification和AVCaptureDeviceWasDisconnectedNotification这两个系统通知,能实时捕获设备插拔事件,自动触发设备列表重新打印。 - RunLoop的作用:控制台程序必须启动RunLoop才能持续接收通知,否则程序会直接退出,根本等不到事件触发。
- 补全设备信息:我帮你补全了原来截断的代码,打印设备的本地化名称和唯一ID,方便你区分不同设备。
- 权限提示:MacOS 10.14及以上版本,需要在程序的
Info.plist中添加NSCameraUsageDescription权限描述,否则可能无法访问摄像头设备,导致设备列表为空。
内容的提问来源于stack exchange,提问作者Jan Kuri
相关产品推荐
相关产品推荐

