【问题标题】:SwiftUI background mode works in simulator but not on a real device?SwiftUI 后台模式在模拟器中有效,但在真实设备上无效?
【发布时间】:2021-05-15 04:13:43
【问题描述】:

我正在我的应用中播放音频。

我可以在模拟器中以后台模式播放音频,但是当我在真实设备中测试应用程序时,一旦应用程序进入后台,音频就会停止。

我在后台模式下有这个:

这就是我播放音频的方式:

import Foundation
import SwiftUI
import Combine
import AVKit
import AVFoundation
import WebKit



//BG Video Player
class PlayerUIView: UIView {
    
    // MARK: Class Property
    
    let playerLayer = AVPlayerLayer()
    
    // MARK: Init
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    init(player: AVPlayer) {
        super.init(frame: .zero)
        self.playerSetup(player: player)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // MARK: Life-Cycle
    
    override func layoutSubviews() {
        super.layoutSubviews()
           
        playerLayer.frame = bounds
            
    }
   
    
    // MARK: Class Methods
    
    private func playerSetup(player: AVPlayer) {
        playerLayer.player = player
        player.actionAtItemEnd = .none
        
        playerLayer.player = player
        playerLayer.videoGravity = .resizeAspectFill
        layer.addSublayer(playerLayer)
    
        
        self.setObserver()
        

    }
    
    func setObserver() {
        NotificationCenter.default.removeObserver(self)
        NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(notification:)),
                                               name: .AVPlayerItemDidPlayToEndTime,
                                               object: playerLayer.player?.currentItem)
    }
    
    @objc func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: .zero, completionHandler: nil)
            self.playerLayer.player?.play()
        }
    }
}



struct PlayerView: UIViewRepresentable {
    
    @Binding var player: AVPlayer
    
    func makeUIView(context: Context) -> PlayerUIView {
        return PlayerUIView(player: player)
           
    }
    
    
    func updateUIView(_ uiView: PlayerUIView, context: UIViewRepresentableContext<PlayerView>) {
        uiView.playerLayer.player = player
        
        //Add player observer.
        uiView.setObserver()
    
    }
    

    
   
}

这就是我使用它的方式:

 struct audioPaleyerView: View {
    
    let audioToPlay = "https://some-UR-to-the-Audio-file"
   


   
    @State private var player = AVPlayer()
     
     var body: some View {


         NavigationView {
            
        

         
                       ZStack{
                        
                        
                        
                        PlayerView(player: $player)
                            .edgesIgnoringSafeArea(.all)

}

}         .onAppear {


            
            let originalUrl = "https://some-UR-to-the-Audio-file"
            let urlString = originalUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
             
            player = AVPlayer(url: URL(string: urlString!)!)
             
         
             player.play()

         
             
     }.onDisappear{
      
        
         
                 }

}

}

最奇怪的是,它在模拟器的后台运行良好,但在真实设备上却失败了!

我有什么遗漏的吗?

编辑:

我找到了这个,但我不确定如何在我的代码中使用它!

也不确定这是否正确?

https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/creating_a_basic_video_player_ios_and_tvos/playing_audio_from_a_video_asset_in_the_background

【问题讨论】:

    标签: swift xcode swiftui


    【解决方案1】:

    OnAppear的开头添加下面的颂歌,

    您的代码如下所示:

    .onAppear {
        // 1
        let session = AVAudioSession.sharedInstance()
        do{
            // 2
            try session.setActive(true)
            // 3
            try session.setCategory(.playback, mode: .default,  options: .defaultToSpeaker)
        } catch{
            // 4
            print(error.localizedDescription)
        }
        
        let originalUrl = "https://some-UR-to-the-Audio-file"
        let urlString = originalUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        
        player = AVPlayer(url: URL(string: urlString!)!)
        
        player.play()
    }
    
    
    1. 返回共享音频会话实例。
    2. 激活应用的音频会话。
    3. 设置音频会话的类别、模式和选项。音频会话的 categorymode 共同定义了您的应用如何使用音频。
    4. 捕获并打印任何可能发生的错误。

    【讨论】:

    • 谢谢。只是美丽。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    相关资源
    最近更新 更多