【问题标题】:Ringer volume slider, swift铃声音量滑块,快速
【发布时间】:2017-02-04 23:44:29
【问题描述】:

所以我的问题是我正在创建一个使用本地通知作为警报的应用程序。唯一的问题是,如果设备的铃声音量降低或静音,它将不会播放任何声音。我知道您无法在后台执行此操作,但是是否可以将滑块链接到铃声音量(如 MPVolume 的滑块)?也可以检查设备是否静音?我只想再次指出,我知道您不能在用户不知情的情况下简单地更改它,但我想知道前面提到的两种方法是否可行。任何有关该主题的帮助将不胜感激。

【问题讨论】:

标签: swift audio volume mute


【解决方案1】:

无法检测 iPhone 是否打开静音开关或更改“铃声”(非音量),因为 Apple 不提供对它们的访问权限。

过去曾经有一个使用 Objective-C 的解决方法,但我不太确定它是否仍然有效,如果您愿意,欢迎您尝试。

AVSystemController

【讨论】:

  • 感谢您的快速回复,我将在接下来的几个小时内研究该方法:)
【解决方案2】:

也可以检查设备是否静音?

这个问题真的很令人沮丧,我不敢相信苹果让它这么难:(

检查音量本身相当简单:

let audioSession = AVAudioSession.sharedInstance()
let volume: Float = audioSession.outputVolume

如果音量为 0.0,则为静音。但真正的问题是铃声开关。

我的解决方案是播放静音(称为“silence.mp3”,时长 1.5 秒且完全静音),并在 0.5 秒后检查是否仍在播放。 这完全受到 SoundSwitch 的启发:https://github.com/moshegottlieb/SoundSwitch

使用中:

MyAudioPlayer.isLoudCheck()
{
    isLoud in

    print("%%% - device is loud = \(isLoud)")
}

我把音频播放器类改成了这个(通常我只是用它来播放声音文件):

import AVFoundation

class MyAudioPlayer: NSObject, AVAudioPlayerDelegate
{
    private static let sharedPlayer: MyAudioPlayer =
    {
        return MyAudioPlayer()
    }()

    public var container = [String : AVAudioPlayer]()

    static func isLoudCheck(completionHandler: @escaping (Bool?) -> ())
    {
        let name = "silence"
        let key = name
        var player: AVAudioPlayer?

        for (file, thePlayer) in sharedPlayer.container
        {
            if file == key
            {
                player = thePlayer
                break
            }
        }

        if player == nil, let resource = Bundle.main.path(forResource: name, ofType: "mp3")
        {
            do
            {
                player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: resource), fileTypeHint: AVFileTypeMPEGLayer3)
            }
            catch
            {
                print("%%% - audio error?")
            }
        }

        if let thePlayer = player
        {
            print("%%% - the player plays")
            thePlayer.delegate = sharedPlayer
            sharedPlayer.container[key] = thePlayer
            thePlayer.play()
        }


        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute:
        {
            if let thePlayer = player
            {
                if thePlayer.isPlaying
                {
                    print("%%% - check: playing")
                    completionHandler(true)
                }
                else
                {
                    print("%%% - check: not playing")
                    completionHandler(false)
                }
            }
        })
    }

    static func isPlaying(key: String) -> Bool?
    {
        return sharedPlayer.container[key]?.isPlaying
    }
}

希望这可以帮助某人:)

【讨论】:

    猜你喜欢
    • 2014-01-20
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多