macOS 开发

阅读: 评论:0

macOS 开发

macOS 开发

文章目录

    • 引言
    • 一、声卡、声音输入输出
      • 1、获取当前声卡ID
      • 2、根据 UID 获取声卡 id
      • 3、根据 ID 获取声卡名字
      • 4、根据 声卡名字 获取 ID
      • 5、获取当前所有有效的输出设备ID
      • 6、切换输出声卡
      • 7、切换输入声卡
      • 8、显示/隐藏声卡
    • 二、音量
      • 1、设置音量
      • 2、设置静音
      • 3、判断是否静音


引言

每隔一段时间就会有人问,怎样获取音量,怎样切换声卡,这里写个方法总结吧。
偏好设置中的声音,在 Cocoa 中主要使用 CoreAudio 和 AudioToolbox 来控制,在使用下面方法后,不妨通读这个框架来加深了解。

常用方法

  • AudioHardwareGetProperty
  • AudioObjectGetPropertyData
  • AudioHardwareSetProperty

一、声卡、声音输入输出

1、获取当前声卡ID


- (void)test7{AudioDeviceID inID = kAudioDeviceUnknown;AudioDeviceID outID = kAudioDeviceUnknown;UInt32 propertySize0 = sizeof(inID);UInt32 propertySize1 = sizeof(outID);AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propertySize0, &inID);AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice , &propertySize1, &outID);NSLog(@"outID : %d",outID);//    NSLog(@"inID : %d",inID);}

2、根据 UID 获取声卡 id


#define KVirtualAudioUID "AudioDevice_UID"- (AudioDeviceID)getAudioIDWithUID:(NSString *)UID{CFStringRef virtualDeviceAudioUID = (__bridge CFStringRef)UID;CFStringRef *inDeviceAudioUID = &virtualDeviceAudioUID;AudioDeviceID virtualAudioDeviceID = kAudioDeviceUnknown;AudioObjectPropertyAddress proprtyAddress = {};proprtyAddress.mSelector = kAudioHardwarePropertyTranslateUIDToDevice;proprtyAddress.mScope = kAudioObjectPropertyScopeGlobal;proprtyAddress.mElement = kAudioObjectPropertyElementMaster;UInt32 inSize = sizeof(inDeviceAudioUID);uint32 outSize = sizeof(virtualAudioDeviceID);OSStatus ret = AudioObjectGetPropertyData(kAudioObjectSystemObject,&proprtyAddress,inSize,inDeviceAudioUID,&outSize,&virtualAudioDeviceID);NSLog(@"ret : %d",ret);NSLog(@"virtualAudioDeviceID : %d",virtualAudioDeviceID);
//    NSLog(@"virtualDeviceAudioUID : %@",(__bridge NSString *)virtualDeviceAudioUID);if (virtualAudioDeviceID == kAudioDeviceUnknown) {NSLog(@"没有发现声卡");return kAudioDeviceUnknown;}return virtualAudioDeviceID;
}

3、根据 ID 获取声卡名字


+ (NSString *)deviceNameForID:(AudioDeviceID)deviceID {UInt32 propertySize = 256;char deviceName[256];AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyDeviceName, &propertySize, deviceName);NSString *deviceNameForID = [NSString stringWithCString:deviceName encoding:NSUTF8StringEncoding];return deviceNameForID;
}

4、根据 声卡名字 获取 ID

+ (AudioDeviceID)deviceIDForName:(NSString *)requestedDeviceName {AudioDeviceID deviceIDForName = kAudioDeviceUnknown;NSArray *availableOutputDeviceIDs = [self availableOutputDeviceIDs];for(NSNumber *deviceIDNumber in availableOutputDeviceIDs) {UInt32 deviceID = [deviceIDNumber unsignedIntValue];NSString *deviceName = [self deviceNameForID:deviceID];if ([requestedDeviceName isEqualToString:deviceName]) {deviceIDForName = deviceID;break;}}return deviceIDForName;
}

5、获取当前所有有效的输出设备ID


+ (NSArray *)availableOutputDeviceIDs {UInt32 propertySize;AudioDeviceID devices[64];int devicesCount = 0;AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propertySize, NULL);AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propertySize, devices);devicesCount = (propertySize / sizeof(AudioDeviceID));NSMutableArray *availableOutputDeviceIDs = [[NSMutableArray alloc] initWithCapacity:devicesCount];for(int i = 0; i < devicesCount; ++i) {if ([self isOutputDevice:devices[i]]) {NSNumber *outputDeviceID = [NSNumber numberWithUnsignedInt:devices[i]];[availableOutputDeviceIDs addObject:outputDeviceID];}}return [NSArray arrayWithArray:availableOutputDeviceIDs];
}+ (BOOL)isOutputDevice:(AudioDeviceID)deviceID {UInt32 propertySize = 256;AudioDeviceGetPropertyInfo(deviceID, 0, false, kAudioDevicePropertyStreams, &propertySize, NULL);BOOL isOutputDevice = (propertySize > 0);return isOutputDevice;
}

6、切换输出声卡

#pragma mark -- 切换输出声卡
+ (void)setOutputDeviceByID:(AudioDeviceID)newDeviceID {UInt32 propertySize = sizeof(UInt32);AudioHardwareSetProperty(kAudioHardwarePropertyDefaultOutputDevice, propertySize, &newDeviceID);}

7、切换输入声卡

#pragma mark -- 切换输入声卡
+ (void)setInputDeviceByID:(AudioDeviceID)newDeviceID {UInt32 propertySize = sizeof(UInt32);AudioHardwareSetProperty(kAudioHardwarePropertyDefaultInputDevice, propertySize, &newDeviceID);}

8、显示/隐藏声卡

在系统偏好设置中 显示/隐藏声卡

- (void)shouldHide:(BOOL)shouldHide audioID:(AudioDeviceID)audioID{AudioDeviceID virtualAudioDeviceID = audioID;int32_t hidden = 0;if (shouldHide) {hidden = 1;}AudioObjectPropertyAddress proprtyAddress = {};proprtyAddress.mSelector = 'hide';proprtyAddress.mScope = kAudioObjectPropertyScopeGlobal;proprtyAddress.mElement = kAudioObjectPropertyElementMaster;int32_t hidden_value = hidden;CFNumberRef number = CFNumberCreate(NULL, kCFNumberSInt32Type, &hidden_value);AudioObjectSetPropertyData(virtualAudioDeviceID, &proprtyAddress, 0, NULL, sizeof(CFNumberRef), &number);CFRelease(number);
}

二、音量


1、设置音量


+ (void)setSystemVolume:(float)theVolume
{float						newValue = theVolume;AudioObjectPropertyAddress	theAddress;AudioDeviceID				defaultDevID;OSStatus					theError = noErr;UInt32						muted;Boolean						canSetVol = YES, muteValue;Boolean						hasMute = YES, canMute = YES;defaultDevID = obtainDefaultOutputDevice();if (defaultDevID == kAudioObjectUnknown) {			//device not found: return without trying to setNSLog(@"Device unknown");return;}//check if the new value is in the correct range - normalize it if notnewValue = theVolume > 1.0 ? 1.0 : (theVolume < 0.0 ? 0.0 : theVolume);if (newValue != theVolume) {NSLog(@"Tentative volume (%5.2f) was out of range; reset to %5.2f", theVolume, newValue);}theAddress.mElement = kAudioObjectPropertyElementMaster;theAddress.mScope = kAudioDevicePropertyScopeOutput;//set the selector to mute or not by checking if under threshold and check if a mute command is availableif ( (muteValue = (newValue < THRESHOLD)) ){theAddress.mSelector = kAudioDevicePropertyMute;hasMute = AudioObjectHasProperty(defaultDevID, &theAddress);if (hasMute){theError = AudioObjectIsPropertySettable(defaultDevID, &theAddress, &canMute);if (theError != noErr || !canMute){canMute = NO;NSLog(@"Should mute device 0x%0x but did not success",defaultDevID);}}else canMute = NO;}else{theAddress.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;}// **** now manage the volume following the what we found ****//be sure the device has a volume commandif (! AudioObjectHasProperty(defaultDevID, &theAddress)){NSLog(@"The device 0x%0x does not have a volume to set", defaultDevID);return;}//be sure the device can set the volumetheError = AudioObjectIsPropertySettable(defaultDevID, &theAddress, &canSetVol);if ( theError!=noErr || !canSetVol ){NSLog(@"The volume of device 0x%0x cannot be set", defaultDevID);return;}//if under the threshold then mute it, only if possible - done/exitif (muteValue && hasMute && canMute){muted = 1;theError = AudioObjectSetPropertyData(defaultDevID, &theAddress, 0, NULL, sizeof(muted), &muted);if (theError != noErr){NSLog(@"The device 0x%0x was not muted",defaultDevID);return;}}else		//else set it{theError = AudioObjectSetPropertyData(defaultDevID, &theAddress, 0, NULL, sizeof(newValue), &newValue);if (theError != noErr){NSLog(@"The device 0x%0x was unable to set volume", defaultDevID);}//if device is able to handle muting, maybe it was muted, so unlock itif (hasMute && canMute){theAddress.mSelector = kAudioDevicePropertyMute;muted = 0;theError = AudioObjectSetPropertyData(defaultDevID, &theAddress, 0, NULL, sizeof(muted), &muted);}}if (theError != noErr) {NSLog(@"Unable to set volume for device 0x%0x", defaultDevID);}
}

2、设置静音

+ (void)applyMute:(Boolean)m
{AudioDeviceID				defaultDevID = kAudioObjectUnknown;AudioObjectPropertyAddress	theAddress;Boolean						hasMute, canMute = YES;OSStatus					theError = noErr;UInt32						muted = 0;defaultDevID = obtainDefaultOutputDevice();if (defaultDevID == kAudioObjectUnknown) {			//device not foundNSLog(@"Device unknown");return;}theAddress.mElement = kAudioObjectPropertyElementMaster;theAddress.mScope = kAudioDevicePropertyScopeOutput;theAddress.mSelector = kAudioDevicePropertyMute;muted = m ? 1 : 0;hasMute = AudioObjectHasProperty(defaultDevID, &theAddress);if (hasMute){theError = AudioObjectIsPropertySettable(defaultDevID, &theAddress, &canMute);if (theError == noErr && canMute){theError = AudioObjectSetPropertyData(defaultDevID, &theAddress, 0, NULL, sizeof(muted), &muted);if (theError != noErr) NSLog(@"Cannot change mute status of device 0x%0x", defaultDevID);}}
}

3、判断是否静音


+ (Boolean)isMuted
{AudioDeviceID				defaultDevID = kAudioObjectUnknown;AudioObjectPropertyAddress	theAddress;Boolean						hasMute, canMute = YES;OSStatus					theError = noErr;UInt32						muted = 0;UInt32                      mutedSize = 4;defaultDevID = obtainDefaultOutputDevice();if (defaultDevID == kAudioObjectUnknown) {			//device not foundNSLog(@"Device unknown");return false;           // works, but not the best return code for this}theAddress.mElement = kAudioObjectPropertyElementMaster;theAddress.mScope = kAudioDevicePropertyScopeOutput;theAddress.mSelector = kAudioDevicePropertyMute;hasMute = AudioObjectHasProperty(defaultDevID, &theAddress);if (hasMute){theError = AudioObjectIsPropertySettable(defaultDevID, &theAddress, &canMute);if (theError == noErr && canMute){theError = AudioObjectGetPropertyData(defaultDevID, &theAddress, 0, NULL, &mutedSize, &muted);if (muted) {return true;}}}return false;
}

本文发布于:2024-02-04 23:00:13,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170718345360523.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:macOS
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23