在Mac os 10.15之后,屏幕录制权限需要获取才能正确录屏,否则只能录制桌面背景以及自身app的影像。即可以截屏,但截不到其他app的内容。
对于Mac os 10.15的屏幕录制权限检测,使用如下方法为最佳:
- (BOOL)canRecordScreen
{
if (@available(macOS 10.15, *)) {
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSUInteger numberOfWindows = CFArrayGetCount(windowList);
NSUInteger numberOfWindowsWithName = 0;
for (int idx = 0; idx < numberOfWindows; idx++) {
NSDictionary *windowInfo = (NSDictionary *)CFArrayGetValueAtIndex(windowList, idx);
NSString *windowName = windowInfo[(id)kCGWindowName];
if (windowName) {
numberOfWindowsWithName++;
} else {
//no kCGWindowName detected -> not enabled
break; //breaking early, numberOfWindowsWithName not increased
}
}
CFRelease(windowList);
return numberOfWindows == numberOfWindowsWithName;
}
return YES;
}
另外一种方法是下面这种?,在权限没有设置的时候没问题,但是在权限设置后,会导致mac os 10.15下的系统崩溃,直接回到登陆界面。所以没有使用这个
- (BOOL)canRecord{
CGDisplayStreamRef stream = CGDisplayStreamCreate(CGMainDisplayID() , 1, 1, kCVPixelFormatType_32ABGR, nil, ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef _Nullable frameSurface, CGDisplayStreamUpdateRef _Nullable updateRef) {
});
BOOL canRecord = stream != NULL;
if (stream) {
CFRelease(stream);
}
NSLog(@"canRecord : %ld",canRecord);
return canRecord;
}
通过截屏都可以向系统获取权限
- (void)showScreenRecordingPrompt{
/* macos 10.14 and lower do not require screen recording permission to get window titles */
if(@available(macos 10.15, *)) {
/*
To minimize the intrusion just make a 1px image of the upper left corner
This way there is no real possibilty to access any private data
*/
CGImageRef c = CGWindowListCreateImage(
CGRectMake(0, 0, 1, 1),
kCGWindowListOptionOnScreenOnly,
kCGNullWindowID,
kCGWindowImageDefault);
CFRelease(screenshot);
}
截取主屏幕全部的内容
CGRect mainRect = CGDisplayBounds(CGMainDisplayID());
CGImageRef desktopImage = CGWindowListCreateImage(mainRect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageBestResolution | kCGWindowImageShouldBeOpaque);
NSImage* image = [[NSImage alloc]initWithCGImage:desktopImage size:_screenAsBtn.frame.size];
CGImageRelease(desktopImage);
截取某个子程序的图片
[_windowList removeAllObjects];
CFArrayRef windowListArray = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray *windows = CFBridgingRelease(CGWindowListCreateDescriptionFromArray(windowListArray));
for(NSMutableDictionary* dic in windows){
NSString* layerStr = [dic objectForKey:(__bridge id)kCGWindowLayer];
CGRect bounds;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[dic objectForKey:@"kCGWindowBounds"], &bounds);
NSRectFromCGRect(bounds);
if ([layerStr intValue] == 0 &&(bounds.size.width>10 && bounds.size.height>10)) {
[_windowList addObject:dic];
}
}
CFRelease(windowListArray);
//下面是for循环中内容,取每张图片
NSMutableDictionary* entry = [_windowList objectAtIndex:i];
int ownerPID = [[entry objectForKey:(__bridge id)kCGWindowNumber] intValue];
NSString* name =[entry objectForKey:(__bridge id)kCGWindowName];
NSString* owerName = [entry objectForKey:(__bridge id)kCGWindowOwnerName];
CGImageRef imageRef = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, ownerPID, kCGWindowImageShouldBeOpaque);
NSImage* image = [[NSImage alloc]initWithCGImage:imageRef size:NSZeroSize];
CGImageRelease(imageRef);
- (void)openSetting{
NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture";
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
}
使用tccutil reset All com.xxx.xxx
来清除,com.xxx.xxx
为bundle id
重置摄像头访问: tccutil reset Camera
重置麦克风访问: tccutil reset Microphone
重置屏幕录制:tccutil reset ScreenCapture
遇到权限一直要获取,获取后提示关闭该程序,进入程序后,又需要获取的死循环。
这里我重启mac就好了,不知道是10.15系统原因否。
参考文章:
1.https://blog.csdn.net/lovechris00/article/details/96979960
2.https://xbuba.com/questions/56597221