Search code examples
macoscocoavideopython-idle

How to detect if video is running on Mac?


I want to know the idle time of Mac. Currently I use this code

CFMutableDictionaryRef properties = 0;
CFTypeRef obj;
mach_port_t masterPort;
io_iterator_t iter;
io_registry_entry_t curObj;

IOMasterPort(MACH_PORT_NULL, &masterPort);

/* Get IOHIDSystem */
IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter);
if (iter == 0)
{
    return -1;
}
else
{
    curObj = IOIteratorNext(iter);
}
if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL)
{
    obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime"));
    CFRetain(obj);
}
else
{
    return -1;
}

uint64_t tHandle = 0;
if (obj)
{
    CFTypeID type = CFGetTypeID(obj);

    if (type == CFDataGetTypeID())
    {
        CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(tHandle)), (UInt8*) &tHandle);
    }
    else if (type == CFNumberGetTypeID())
    {
        CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &tHandle);
    }
    else
    {
        // error
        tHandle = 0;
    }

    CFRelease(obj);

    tHandle /= 1000000; // return as milliseconds
}
else
{
    tHandle = -1;
}

CFRelease((CFTypeRef)properties);
IOObjectRelease(curObj);
IOObjectRelease(iter);
return (double)tHandle;

However, I want the idle time to keep 0 if any video is running.

Is there any code sample or library to check? (include video running on iTunes, VLC, youtube on browser or any other video applications)


Solution

  • I can interpret your question several ways:

    How to determine when the screensaver kicks in?

    Check the following script (original answer):

    #!/bin/bash
    
    systemSleepTimeMinutes=`pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'`
    
    if [ $systemSleepTimeMinutes -gt "0" ]; then
        systemSleepTime=`echo "$systemSleepTimeMinutes * 60" | bc`
        devicesIdleTime=`ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'`
        secondsBeforeSleep=`echo "$systemSleepTime - $devicesIdleTime" | bc`
        echo "Time before sleep (sec): $secondsBeforeSleep"
        exit 0
    else
        echo "The system is set to not sleep."
        exit 0
    fi
    

    In case the screensaver is suppressed, for example by VLC, the result is:

    The system is set to not sleep.

    Otherwise it returns the time until the screensaver kicks in, for example:

    Time before sleep (sec): 899.88056

    Run the script above through NSTask or NSAppleScript and parse the result.
    Please note "sleep" may also rever to the screensaver, depending on which one kicks in first.

    How to determine wether the screensaver is suppressed?

    The following line does the trick:

    pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'
    

    In case the screensaver is suppressed it returns 0.
    Run the line above through NSTask or NSAppleScript and parse the result.

    How to suppress the screensaver?

    The official Apple documentation (including code snippet):
    How can I prevent system sleep while my application is running?


    EDIT (Response to comment)

    However, is there a built-in method that works the same as this script?

    I'm not familiar with such a method. I actually doubt it exists.

    Quick NSAppleScript example:

    NSString *source = @"do shell script \"pmset -g | grep \\\"^[ ]*sleep\\\" | awk '{ print $2 }'\"";
    NSAppleScript *script= [[NSAppleScript alloc] initWithSource:source];
    NSDictionary *scriptError = nil;
    NSAppleEventDescriptor *descriptor=[script executeAndReturnError:&scriptError];
    if(scriptError) {
        NSLog(@"Error: %@",scriptError);
    } else {
        if ([[descriptor stringValue] intValue] == 0) {
            NSLog(@"Screensaver suppressed.");
        } else {
            NSLog(@"Screensaver not suppressed.");
        }
    }
    

    Just don't be reticent about using NSTask or NSAppleScript :)