Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture screen with CGDisplayStream

Tags:

macos

xcode4.5

I'm trying to implement a feature in my app that will record the screen. I have bits of code that I have found in some sample code and a WWDC 2012 video.

So far I have this.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    // Get a list of displays.  Copied from working apple source code.
    [self getDisplayList];

    DisplayRegistrationCallBackSuccessful = NO;

    // Register the event for modifying displays.
    CGError err =  CGDisplayRegisterReconfigurationCallback(DisplayRegisterReconfigurationCallback, NULL);
    if (err == kCGErrorSuccess) {
        DisplayRegistrationCallBackSuccessful = YES;
    }

    // Insert code here to initialize your application

    const void *keys[1] = { kCGDisplayStreamSourceRect };
    const void *values[1] = { CGRectCreateDictionaryRepresentation(CGRectMake(0, 0, 100, 100)) };
    CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

    stream = CGDisplayStreamCreate(displays[0], 100, 100, '420f', properties,
                                                  ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) {
                                                      NSLog(@"Next Frame"); // This line is never called.
                                                  });

    runLoop = CGDisplayStreamGetRunLoopSource(stream);

    CGError err = CGDisplayStreamStart(stream); 
    if (err == CGDisplayNoErr) {
        NSLog(@"Works");
    } else {
        NSLog(@"Error: %d", err);
    }
}

The problem I am encountering is that the callback block for the DisplayStream is not being called. I am not getting any errors or warnings. Is there something I'm missing or that I've done wrong?

like image 449
David Skrundz Avatar asked Dec 24 '12 06:12

David Skrundz


2 Answers

I solved the problem by using CGDisplayStreamCreateWithDispatchQueue and passing dispatch_queue_create("queue for dispatch", NULL); as the queue.

like image 144
David Skrundz Avatar answered Sep 20 '22 12:09

David Skrundz


For what it's worth, it looks like you're getting the runloop source, but then not adding it to the current run loop (CFRunLoopAddSource)

like image 29
xtophyr Avatar answered Sep 21 '22 12:09

xtophyr