objective-c - 检测系统音量何时在 mac 上发生变化?

标签 objective-c

有谁知道是否可以创建一个监听器来检测 Mac 系统音量何时发生变化?如果是这样,您知道我在哪里可以找到有关如何完成此操作的示例吗?

最佳答案

概念

所以,希望有更好的方法来处理这个问题,但这是一个概念:

分拆一个新线程来观察 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

如果这似乎是您喜欢的方法,您可能需要考虑设置一个带有委托(delegate)回调或 block 之类的对象。

警告

此解决方案需要一个后台线程来不断地观察变化。它应该很低调,因为它是如此简单的检查,但值得一提。

关于objective-c - 检测系统音量何时在 mac 上发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9147133/

相关文章:

objective-c - Apple 模板在转换为 BOOL 后是否包含错误?

ios - SpriteKit 和可滚动列表

objective-c - 阻止窗口打开(无窗口应用程序)

objective-c - 使用 DidSelectRowAtIndexPath 更改 NSMutableArray

iphone - 所有触地事件上的按钮声音

objective-c - NSWindow makeKeyAndOrderFront 使窗口出现,但不是 Key 或 Front

iphone - 您如何在 iOS 中将模型与 UIButton(或通常的 UIViews)相关联?

objective-c - 弹出 View 时自定义导航栏背景不会恢复

ios - 摆脱 SIGABRT 错误

objective-c - 如何在 iOS 上模拟 HTTP 表单(POST)提交