【问题标题】:How to stream audio from URL without downloading mp3 file on device如何从 URL 流式传输音频而不在设备上下载 mp3 文件
【发布时间】:2018-07-11 07:45:58
【问题描述】:

如何在 Swift 中从 URL 流式传输音频而不在设备上下载 mp3 文件?我需要导入什么?我需要某些库吗?向 info.plist 添加任何内容?请评论您的代码。

【问题讨论】:

    标签: ios swift xcode url audio


    【解决方案1】:

    对于在线流媒体,您必须使用 AVFoundation 框架。

    var player: AVPlayer!
    
    let url = URL.init(string: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3")
    player = AVPlayer.init(url: url!)
    

    玩:

        player.play()
    

    暂停:

        player.pause()
    

    【讨论】:

    • 您好,我试过了,但没有播放任何内容。我已导入 AVFoundation 并导入 AVKit 并使用了此代码,但歌曲无法播放。有什么建议吗?
    • @user8802333,你能分享你想流式传输的网址吗?
    • @user8802333 确保您的设备未处于静音模式...要在静音模式下播放音频,请使用以下代码行...try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
    【解决方案2】:

    您可以使用 iOS AVPLayer 从 url 流式传输音频。

    var player: AVPlayer!
    let url  = URL.init(string:   "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3")
    
    let playerItem: AVPlayerItem = AVPlayerItem(url: url!)
    player = AVPlayer(playerItem: playerItem)
    
    let playerLayer = AVPlayerLayer(player: player!)
    
    playerLayer?.frame = CGRect(x: 0, y: 0, width: 10, height: 50)
            self.view.layer.addSublayer(playerLayer!)
    player.play()
    

    【讨论】:

    • 您好,我试过了,但没有播放任何内容。我已导入 AVFoundation 并导入 AVKit 并使用了此代码,但歌曲无法播放。有什么建议吗?
    • 歌曲无法播放,没有错误或弹出任何内容。
    • 确保网址有效
    【解决方案3】:

    你可以去

     import AVFoundation
    
    var progressTimer:Timer?
    {
        willSet {
            progressTimer?.invalidate()
        }
    }
    var playerStream: AVPlayer?
    var playerItem: AVPlayerItem?
    
    func playerStream(urlStream : String) {
        if let playerStream = playerStream {
            if playerStream.isPlaying {
                stopProgressTimer()
                playerStream.pause() 
            } else {  
                startProgressTimer()
                playerStream.play()
            }  
        } else {
            if let urlStr = urlStream.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
                if let TempURL = URL.init(string: urlStr) {
                    playerItem = AVPlayerItem(url: TempURL)
                    playerStream = AVPlayer(playerItem: playerItem)
                    NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem)
                } 
            } 
        } 
    }
    
    func playerItemDidPlayToEndTime() {
         stopProgressTimer()
         self.playProgressView.progress = 0.0
         if let playerStream = self.playerStream {
            playerStream.replaceCurrentItem(with: playerItem)
            playerStream.seek(to: kCMTimeZero)
           // playerStream.seek(to: .zero) swift 4.0
        } 
    }
    
    func stopProgressTimer() {
        progressTimer?.invalidate()
        progressTimer = nil
    }
    
    func startProgressTimer() {
        if #available(iOS 10.0, *) {
            progressTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true){ [weak self] in
                self?.updateProgressTimer()
            }
        } else {
            progressTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateProgressTimer), userInfo: nil, repeats: true)
        }
    }
    
    @objc func updateProgressTimer() {
        if let playerItem = playerItem {
            if let pa = playerStream {
                let floatTime = Float(CMTimeGetSeconds(pa.currentTime()))
                let floatTimeDu = Float(CMTimeGetSeconds(playerItem.duration))
    
                playProgressView.progress = Double(floatTime / floatTimeDu)
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我用你的网址测试它并且它工作

          var player: AVPlayer?
          let url = "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
          let playerItem = AVPlayerItem( url:NSURL( string:url )! as URL )
          player = AVPlayer(playerItem:playerItem)
          player!.rate = 1.0;
      
              player!.play()
      

      【讨论】:

        【解决方案5】:
        class MusicPlayer {
            public static var instance = MusicPlayer()
            var player = AVPlayer()
        
            func initPlayer(url: String) {
                guard let url = URL(string: url) else { return }
                let playerItem = AVPlayerItem(url: url)
                player = AVPlayer(playerItem: playerItem)
                playAudioBackground()
            }
            
            func playAudioBackground() {
                do {
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers, .allowAirPlay])
                    print("Playback OK")
                    try AVAudioSession.sharedInstance().setActive(true)
                    print("Session is Active")
                } catch {
                    print(error)
                }
            }
            
            func pause(){
                player.pause()
            }
            
            func play() {
                player.play()
            }
        }
        

        此类将在后台播放音乐并播放任何音频/视频 URL。

        【讨论】:

        • Anil,谢谢,在模拟器上我收到如下消息:load failed with error Error Domain=NSURLErrorDomain Code=-999 "cancelled"
        • “应用程序传输安全”导致 AFNetworking 错误代码:-999。如果您尝试访问没有 SSL 的服务器,请添加如下屏幕截图所示的密钥。 i.stack.imgur.com/gsMRP.png 在构建设置中。
        • 嗨 @AnilKumar,嗯,但是相同的 URL 可以在手机上使用吗?它们是在浏览器中正常工作的常见网址............
        • 类名应该大写
        【解决方案6】:
            func playAudioBackground() {
                do {
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers, .allowAirPlay])
                    print("Playback OK")
                    try AVAudioSession.sharedInstance().setActive(true)
                    print("Session is Active")
                } catch {
                    print(error)
                }
            }
        

        应该是

            func playAudioBackground() {
                do {
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers])
                    print("Playback OK")
                    try AVAudioSession.sharedInstance().setActive(true)
                    print("Session is Active")
                } catch {
                    print(error)
                }
            }
        

        因为 .allowAirPlay 不允许与 AVAudioSession.Category.playback 一起使用,并且会导致真实设备抛出异常。它在模拟器上运行良好,但在设备上运行良好,因此您的音频会话将无法正确配置。

        我会回复它,但我的声誉不够高,无法让我...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-09
          • 2013-08-07
          • 1970-01-01
          相关资源
          最近更新 更多