ios 如何以编程方式感知 iPhone 静音开关?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/287543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:23:37  来源:igfitidea点击:

How to programmatically sense the iPhone mute switch?

iosaudioavaudiosession

提问by Olie

I can't seem to find in the SDK how to programatically sense the mute button/switch on the iPhone. When my app plays background music, it responds properly to the volume button without me having any code to follow that but, when I use the mute switch, it just keeps playing away.

我似乎无法在 SDK 中找到如何以编程方式感知 iPhone 上的静音按钮/开关。当我的应用程序播放背景音乐时,它会正确响应音量按钮,而我没有任何代码可以遵循,但是,当我使用静音开关时,它只是继续播放。

How do I test the position of mute?

如何测试静音位置?

(NOTE: My program has its own mute switch, but I'd like the physical switch to override that.)

(注意:我的程序有自己的静音开关,但我希望物理开关覆盖它。)

采纳答案by Olie

Thanks, JPM. Indeed, the link you provide leads to the correct answer (eventually. ;) For completeness (because S.O. should be a source of QUICK answers! )...

谢谢,JPM。事实上,您提供的链接会导致正确的答案(最终。;)为了完整性(因为 SO 应该是快速答案的来源!)...

// "Ambient" makes it respect the mute switch
// Must call this once to init session
if (!gAudioSessionInited)
{
    AudioSessionInterruptionListener    inInterruptionListener = NULL;
    OSStatus    error;
    if ((error = AudioSessionInitialize (NULL, NULL, inInterruptionListener, NULL)))
    {
        NSLog(@"*** Error *** error in AudioSessionInitialize: %d.", error);
    }
    else
    {
        gAudioSessionInited = YES;
    }
}

SInt32  ambient = kAudioSessionCategory_AmbientSound;
if (AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (ambient), &ambient))
{
    NSLog(@"*** Error *** could not set Session property to ambient.");
}

回答by Chris Ladd

I answered a similar question here (link). The relevant code:

在这里回答了一个类似的问题(链接)。相关代码:

 -(BOOL)silenced {
     #if TARGET_IPHONE_SIMULATOR
         // return NO in simulator. Code causes crashes for some reason.
         return NO;
     #endif

    CFStringRef state;
    UInt32 propertySize = sizeof(CFStringRef);
    AudioSessionInitialize(NULL, NULL, NULL, NULL);
    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
    if(CFStringGetLength(state) > 0)
            return NO;
    else
            return YES;

    }

回答by Jane Sales

Some of the code in other answers (including the accepted answer) may not work if you aren't in the ambient mode, where the mute switch is respected.

如果您不在环境模式下,其他答案(包括接受的答案)中的一些代码可能无法工作,在这种模式下静音开关受到尊重。

I wrote the routine below to switch to ambient, read the switch, and then return to the settings I need in my app.

我编写了下面的例程来切换到环境,读取开关,然后返回到我在我的应用程序中需要的设置。

-(BOOL)muteSwitchEnabled {

#if TARGET_IPHONE_SIMULATOR
    // set to NO in simulator. Code causes crashes for some reason.
    return NO;
#endif

// go back to Ambient to detect the switch
AVAudioSession* sharedSession = [AVAudioSession sharedInstance];
[sharedSession setCategory:AVAudioSessionCategoryAmbient error:nil];

CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);

BOOL muteSwitch = (CFStringGetLength(state) <= 0);
NSLog(@"Mute switch: %d",muteSwitch);

// code below here is just restoring my own audio state, YMMV
_hasMicrophone = [sharedSession inputIsAvailable];
NSError* setCategoryError = nil;

if (_hasMicrophone) {

    [sharedSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &setCategoryError];

    // By default PlayAndRecord plays out over the internal speaker.  We want the external speakers, thanks.
    UInt32 ASRoute = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
                             sizeof (ASRoute),
                             &ASRoute
                             );
}
else
    // Devices with no mike don't support PlayAndRecord - we don't get playback, so use just playback as we don't have a microphone anyway
    [sharedSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];

if (setCategoryError)
    NSLog(@"Error setting audio category! %@", setCategoryError);

return muteSwitch;
}

回答by Martin Cowie

To find out the state of the mute switch andthe volume control I wrote these two functions. These are ideal if you wish to warn the user before they try creating audio output.

为了找出静音开关音量控制的状态,我写了这两个函数。如果您希望在用户尝试创建音频输出之前警告他们,这些是理想的选择。

-(NSString*)audioRoute
{
    CFStringRef state;
    UInt32 propertySize = sizeof(CFStringRef);
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
    if( n )
    {
        // TODO: Throw an exception
        NSLog( @"AudioSessionGetProperty: %@", osString( n ) );
    }

    NSString *result = (NSString*)state;
    [result autorelease];
    return result;
}

-(Float32)audioVolume
{
    Float32 state;
    UInt32 propertySize = sizeof(CFStringRef);
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume, &propertySize, &state);
    if( n )
    {
        // TODO: Throw an exception
        NSLog( @"AudioSessionGetProperty: %@", osString( n ) );
    }
    return state;
}

回答by Haemish Graham

-(BOOL)isDeviceMuted
{
 CFStringRef state;
 UInt32 propertySize = sizeof(CFStringRef);
 AudioSessionInitialize(NULL, NULL, NULL, NULL);
 AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
 return (CFStringGetLength(state) > 0 ? NO : YES);
}

回答by Mark24x7

I followed the general theory here and got this to work http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

我遵循了这里的一般理论并使它起作用 http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

Here is a recap: Play a short silent sound. Time how long it takes to play. If the mute switch is on, the playing of the sound will come back much shorter than the sound itself. I used a 500ms sound and if the sound played in less than this time, then the mute switch was on. I use Audio Services to play the silent sound (which always honors the mute switch). This article says that you can use AVAudioPlayer to play this sound. If you use AVAudioPlayer, I assume you'll need to setup your AVAudioSession's category to honor the mute switch, but I have not tried it`.

这是一个回顾:播放一个简短的无声的声音。时间玩多久。如果静音开关打开,声音的播放将比声音本身短得多。我使用了 500 毫秒的声音,如果声音播放的时间少于这个时间,则静音开关打开。我使用音频服务来播放无声的声音(它总是尊重静音开关)。这篇文章说你可以使用 AVAudioPlayer 来播放这个声音。如果您使用 AVAudioPlayer,我假设您需要设置 AVAudioSession 的类别以支持静音开关,但我还没有尝试过。

回答by jpm

Olie,

奥利,

I believe you can find the answer to your question here:

我相信你可以在这里找到你的问题的答案:

https://devforums.apple.com/message/1135#1135

https://devforums.apple.com/message/1135#1135

I'm assuming you have access to the Developer Forums at Apple.com :)

我假设您可以访问 Apple.com 上的开发者论坛 :)

回答by slamor

Using Ambientmode for playing a video and PlayAndRecordmode for recording a video on camera screen, resolves the issue in our case.

使用环境模式播放视频,使用PlayAndRecord模式在相机屏幕上录制视频,解决了我们的案例中的问题。

The code in application:didFinishLaunchingWithOptions:

application:didFinishLaunchingWithOptions 中的代码:

NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];

The code in viewWillAppear on cameraController, if you have to use camera or recording in your app

在cameraController 上的viewWillAppear 中的代码,如果您必须在您的应用程序中使用相机或录制

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

The code in viewWillDisappear on cameraController

在cameraController上viewWillDisappear中的代码

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];

Using these lines our Application records and plays a video and mute switch works perfectly under both iOS8 and iOS7!!!

使用这些行,我们的应用程序可以在 iOS8 和 iOS7 下完美地录制和播放视频和静音开关!!!

回答by Govind Prajapati

For Swift

对于斯威夫特

Below framework works perfectly in device

下面的框架在设备中完美运行

https://github.com/akramhussein/Mute

https://github.com/akramhussein/Mute

Just install using podor download from Git

只需使用pod安装或从 Git 下载

pod 'Mute'

and use like below code

并使用如下代码

import UIKit
import Mute

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel! {
        didSet {
            self.label.text = ""
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Notify every 2 seconds
        Mute.shared.checkInterval = 2.0

        // Always notify on interval
        Mute.shared.alwaysNotify = true

        // Update label when notification received
        Mute.shared.notify = { m in
            self.label.text = m ? "Muted" : "Not Muted"
        }

        // Stop after 5 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            Mute.shared.isPaused = true
        }

        // Re-start after 10 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
            Mute.shared.isPaused = false
        }
    }

}