在SwiftUI中观察系统音量

3
我正在尝试在我的应用程序中显示音量指示器,但首先我需要监视系统的当前音量。

我正在使用观察者,虽然打印语句显示了正确的值,但UI从未显示。

import SwiftUI
import MediaPlayer

struct ContentView: View {
    @State var vol: Float = 1.0

    // Audio session object
    private let session = AVAudioSession.sharedInstance()
    // Observer
    private var progressObserver: NSKeyValueObservation!

    init() {
            do {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
                try session.setActive(true, options: .notifyOthersOnDeactivation)
                self.vol = 1.0
            } catch {
                print("cannot activate session")
            }

            progressObserver = session.observe(\.outputVolume) { [self] (session, value) in
                print(session.outputVolume)
                self.vol = session.outputVolume
            }
        }

    var body: some View {
        Text(String(self.vol))
    }
}

// 已修复(将类别设置为环境音乐)(请参见上面的代码更新) 此外,每次启动应用程序时,它都会停止当前正在播放的所有音乐。


1
您正在声明活动音频会话,因此它将停止任何其他音频会话。这是因为默认类别为独奏环境声。您需要将音频会话类别设置为环境声。 - Paulw11
@Paulw11 感谢您建议将类别设置为环境。这解决了那个问题。 - Marcelo
1个回答

3
解决了。创建一个符合ObservableObject的类,并在视图中使用ObservedObject属性。此外,音量观察器在模拟器上不起作用,只能在设备上使用。

VolumeObserver.swift

import Foundation
import MediaPlayer

final class VolumeObserver: ObservableObject {
    
    @Published var volume: Float = AVAudioSession.sharedInstance().outputVolume
    
    // Audio session object
    private let session = AVAudioSession.sharedInstance()
    
    // Observer
    private var progressObserver: NSKeyValueObservation!
    
    func subscribe() {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
            try session.setActive(true, options: .notifyOthersOnDeactivation)
        } catch {
            print("cannot activate session")
        }
        
        progressObserver = session.observe(\.outputVolume) { [self] (session, value) in
            DispatchQueue.main.async {
                self.volume = session.outputVolume
            }
        }
    }
    
    func unsubscribe() {
        self.progressObserver.invalidate()
    }
    
    init() {
        subscribe()
    }
}

ContentView.swift

import SwiftUI
import MediaPlayer

struct ContentView: View {

    @ObservedObject private var volObserver = VolumeObserver()
    
    init() {
        print(volObserver.volume)
    }
    
    var body: some View {
        Text(String(volObserver.volume))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

即使音量为0.0或1.0,观察者是否可以做出响应?如果音量设置为最大/最小值,观察者似乎不会响应... - Benjamin B.
我一定漏掉了什么,因为给出的答案不包含值 val - Kurt L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接