【问题标题】:how to detect the changes of volume in iOS?如何检测iOS中音量的变化?
【发布时间】:2020-03-17 10:33:32
【问题描述】:

我已经阅读了stackOverFlow和gitHub提供的很多解决方案,它们都对我不起作用。我尝试了以下两种方式:

  1. 使用音频会话
override func viewWillAppear(_ animated: Bool) {
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setActive(true, options: [])
        } catch {
            print("error")
        }
        // this print shows, got the current volume.
        //but what I need is the notification of the change of volume
        print("view will appear ,this volume is \(audioSession.outputVolume)")
        audioSession.addObserver(self,
                                 forKeyPath: "outputVolume",
                                 options: [.new],
                                 context: nil)
    }

override class func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        if keyPath == "outputVolume"{
            let audioSession = AVAudioSession.sharedInstance()
            let volume = audioSession.outputVolume
            //this print doesn't shows up
            print("observed volume is \(volume)")
        }
    }
  1. 使用通知
    override func viewWillAppear(_ animated: Bool) {
        NotificationCenter.default.addObserver(self, selector: #selector(observed(_:)), name: Notification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification"), object: nil)
    }

    @objc func observed(_ notification: Notification){
        print("observed")
    }

顺便说一下,我用的是模拟器(iPhone11,iOS13.1),Xcode版本是11.1

【问题讨论】:

    标签: ios swift volume detect


    【解决方案1】:

    尝试使用以下内容:

    import UIKit
    import MediaPlayer
    import AVFoundation
    
    class ViewController: UIViewController {
    
        private var audioLevel: Float = 0.0
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            listenVolumeButton()
        }
    
        func listenVolumeButton() {
    
            let audioSession = AVAudioSession.sharedInstance()
            do {
                try audioSession.setActive(true, options: [])
                audioSession.addObserver(self, forKeyPath: "outputVolume",
                                         options: NSKeyValueObservingOptions.new, context: nil)
                audioLevel = audioSession.outputVolume
            } catch {
                print("Error")
            }
        }
    
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
            if keyPath == "outputVolume" {
                let audioSession = AVAudioSession.sharedInstance()
                if audioSession.outputVolume > audioLevel {
                    print("Hello")
                    audioLevel = audioSession.outputVolume
                }
                if audioSession.outputVolume < audioLevel {
                    print("Goodbye")
                    audioLevel = audioSession.outputVolume
                }
                if audioSession.outputVolume > 0.999 {
                    (MPVolumeView().subviews.filter { NSStringFromClass($0.classForCoder) == "MPVolumeSlider" }.first as? UISlider)?.setValue(0.9375, animated: false)
                    audioLevel = 0.9375
                }
    
                if audioSession.outputVolume < 0.001 {
                    (MPVolumeView().subviews.filter { NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(0.0625, animated: false)
                    audioLevel = 0.0625
                }
            }
        }
    }
    

    希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      您需要确保应用的音频会话处于活动状态才能使其正常工作:

      let audioSession = AVAudioSession.sharedInstance()
       do {
         try audioSession.setActive(true)
         startObservingVolumeChanges()
          } catch {
           print(“Failed to activate audio session")
         }
      

      所以如果你只需要查询当前系统卷:

      let volume = audioSession.outputVolume
      

      或者我们可以收到这样的更改通知:

      private struct Observation {
         static let VolumeKey = "outputVolume"
         static var Context = 0
      
      }
      
      func startObservingVolumeChanges() {
         audioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: 
      [.Initial, .New], context: &Observation.Context)
      }
      
      override func observeValueForKeyPath(keyPath: String?, ofObject object: 
      AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) 
      {
          if context == &Observation.Context {
          if keyPath == Observation.VolumeKey, let volume = (change? 
        [NSKeyValueChangeNewKey] as? NSNumber)?.floatValue {
              // `volume` contains the new system output volume...
              print("Volume: \(volume)")
          }
      } else {
          super.observeValueForKeyPath(keyPath, ofObject: object, change: change, 
       context: context)
         }
      }
      

      在被释放之前不要忘记停止观察:

      func stopObservingVolumeChanges() {
          audioSession.removeObserver(self, forKeyPath: Observation.VolumeKey, 
      context: &Observation.Context)
      }
      

      【讨论】:

        猜你喜欢
        • 2022-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-08
        • 2017-06-12
        • 2013-07-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多