Определить, когда системная громкость меняется на Mac? - PullRequest
2 голосов
/ 05 февраля 2012

Кто-нибудь знает, возможно ли создать прослушиватель для определения изменения громкости системы Mac?Если да, знаете ли вы, где я могу найти пример того, как этого добиться?

1 Ответ

2 голосов
/ 05 февраля 2012

Концепция

Итак, надеюсь, есть лучший способ справиться с этим, но это концепция:

Раскрутите новый поток, чтобы посмотреть атрибут громкости, найденный в AudioToolbox. Затем пусть это вызовет какой-нибудь обратный вызов.

#import "AppDelegate.h"
#define kVolumeKey @"currentvolumeforvolumemonitorkey"

@implementation AppDelegate

@synthesize window = _window;

/* Credit to CocoaDev Starts Now */
/* http://www.cocoadev.com/index.pl?SoundVolume */
+(AudioDeviceID)defaultOutputDeviceID
{
    AudioDeviceID   outputDeviceID = kAudioObjectUnknown;

    // get output device device
    UInt32 propertySize = 0;
    OSStatus status = noErr;
    AudioObjectPropertyAddress propertyAOPA;
    propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal;
    propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
    propertyAOPA.mSelector = kAudioHardwarePropertyDefaultOutputDevice;

    if (!AudioHardwareServiceHasProperty(kAudioObjectSystemObject, &propertyAOPA))
    {
        NSLog(@"Cannot find default output device!");
        return outputDeviceID;
    }

    propertySize = sizeof(AudioDeviceID);

    status = AudioHardwareServiceGetPropertyData(kAudioObjectSystemObject, &propertyAOPA, 0, NULL, &propertySize, &outputDeviceID);

    if(status) 
    {
        NSLog(@"Cannot find default output device!");
    }
    return outputDeviceID;
}

+(float)volume 
{
    Float32         outputVolume;

    UInt32 propertySize = 0;
    OSStatus status = noErr;
    AudioObjectPropertyAddress propertyAOPA;
    propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
    propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
    propertyAOPA.mScope = kAudioDevicePropertyScopeOutput;

    AudioDeviceID outputDeviceID = [AppDelegate defaultOutputDeviceID];

    if (outputDeviceID == kAudioObjectUnknown)
    {
        NSLog(@"Unknown device");
        return 0.0;
    }

    if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA))
    {
        NSLog(@"No volume returned for device 0x%0x", outputDeviceID);
        return 0.0;
    }

    propertySize = sizeof(Float32);

    status = AudioHardwareServiceGetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, &propertySize, &outputVolume);

    if (status)
    {
        NSLog(@"No volume returned for device 0x%0x", outputDeviceID);
        return 0.0;
    }

    if (outputVolume < 0.0 || outputVolume > 1.0) return 0.0;

    return outputVolume;
}
/* Thanks CocoaDev! */


- (void)dealloc
{
    [super dealloc];
}

- (void)volumeDidChangeToLevel: (CGFloat)level
{
    NSLog(@"LEVEL: %f", level);
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
    ^{
        [[NSUserDefaults standardUserDefaults] setFloat: [[self class] volume] forKey: kVolumeKey];
        [[NSUserDefaults standardUserDefaults] synchronize];
        for(CGFloat volLevel = [[self class] volume];; volLevel = [[self class] volume])
        {
             if (volLevel != [[NSUserDefaults standardUserDefaults] floatForKey: kVolumeKey])
             {
                 [[NSUserDefaults standardUserDefaults] setFloat: [[self class] volume] forKey: kVolumeKey];
                 [[NSUserDefaults standardUserDefaults] synchronize];

                 dispatch_async(dispatch_get_main_queue(),
                 ^{
                     [self volumeDidChangeToLevel: volLevel];
                 });
             }
        }
    });
}

@end

Если вам подходит такой подход, возможно, вы захотите создать объект с обратным вызовом делегата, блоком или чем-то еще.

Протест

Это решение требует одного фонового потока для постоянного отслеживания изменений . Это должно быть довольно сдержанно, потому что это такая простая проверка, но стоит упомянуть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...