每隔一段时间就会有人问,怎样获取音量,怎样切换声卡,这里写个方法总结吧。
偏好设置中的声音,在 Cocoa 中主要使用 CoreAudio 和 AudioToolbox 来控制,在使用下面方法后,不妨通读这个框架来加深了解。
常用方法
- (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);}
#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;
}
+ (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;
}
+ (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;
}
+ (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;
}
#pragma mark -- 切换输出声卡
+ (void)setOutputDeviceByID:(AudioDeviceID)newDeviceID {UInt32 propertySize = sizeof(UInt32);AudioHardwareSetProperty(kAudioHardwarePropertyDefaultOutputDevice, propertySize, &newDeviceID);}
#pragma mark -- 切换输入声卡
+ (void)setInputDeviceByID:(AudioDeviceID)newDeviceID {UInt32 propertySize = sizeof(UInt32);AudioHardwareSetProperty(kAudioHardwarePropertyDefaultInputDevice, propertySize, &newDeviceID);}
在系统偏好设置中 显示/隐藏声卡
- (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);
}
+ (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);}
}
+ (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);}}
}
+ (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小时内删除。
留言与评论(共有 0 条评论) |