如何在iOS中使用AVPlayer缓冲音频?

如何在iOS中使用AVPlayer缓冲音频?,第1张

概述我想从互联网播放流音频.我编写了播放流的代码,但它没有任何缓冲区,所以如果信号弱则应用程序停止播放音频.这是我的代码: import UIKitimport AVFoundationimport MediaPlayerimport AudioToolboxclass ViewController: UIViewController {var playerItem:AVPlayerIt 我想从互联网播放流音频.我编写了播放流的代码,但它没有任何缓冲区,所以如果信号弱则应用程序停止播放音频.这是我的代码:

import UIKitimport AVFoundationimport MediaPlayerimport AudioToolBoxclass VIEwController: UIVIEwController {var playerItem:AVPlayerItem?var player:AVPlayer?@IBOutlet weak var Playbutton: UIbutton!overrIDe func vIEwDIDLoad() {    super.vIEwDIDLoad()    var buffer = AVAudioBuffer ()    let url = NSURL (string: "http://radio.afera.com.pl/afera64.aac")    playerItem = AVPlayerItem(URL: url!)    player = AVPlayer(playerItem: playerItem!)}overrIDe func dIDReceiveMemoryWarning() {    super.dIDReceiveMemoryWarning()    // dispose of any resources that can be recreated.}@IBAction func PlaybuttonTapped(sender: AnyObject){    if ((player!.rate != 0) && (player!.error == nil))    {        player!.pause()        Playbutton.setimage(UIImage(named:"Play"),forState: UIControlState.normal)    }    else    {        player!.play()        Playbutton.setimage(UIImage(named:"Stop"),forState:UIControlState.normal)    }}}

我不知道如何缓冲此流.我搜索了苹果文档,但在Swift中找不到任何东西.

我发现类似AVAudioBuffer但我不知道如何使用它,如果它正确解决这个问题.

附: C#上有关于MSDN的文档,在Swift的情况下Apple是类似的吗?

@R_419_6120@ 答案是创建一个错误委托,每次播放器停止时启动选择器(当网络连接中断或流未正确加载时错误发生变化):

这是代表,就在我的RadioPlayer类之外和之上:

protocol errorMessageDelegate {func errorMessageChanged(newVal: String)}

类:

import Foundationimport AVFoundationimport UIKitclass RadioPlayer : NSObject {static let sharedInstance = RadioPlayer()var instanceDelegate:sharedInstanceDelegate? = nilvar sharedInstanceBool = false {    dIDSet {        if let delegate = self.instanceDelegate {            delegate.sharedInstanceChanged(self.sharedInstanceBool)        }    }}private var player = AVPlayer(URL: NSURL(string: Globals.radioURL)!)private var playerItem = AVPlayerItem?()private var isPlaying = falsevar errorDelegate:errorMessageDelegate? = nilvar errorMessage = "" {    dIDSet {        if let delegate = self.errorDelegate {            delegate.errorMessageChanged(self.errorMessage)        }    }}overrIDe init() {    super.init()    errorMessage = ""    let asset: AVURLAsset = AVURLAsset(URL: NSURL(string: Globals.radioURL)!,options: nil)    let statusKey = "tracks"    asset.loadValuesAsynchronouslyForKeys([statusKey],completionHandler: {        var error: NSError? = nil        dispatch_async(dispatch_get_main_queue(),{            let status: AVkeyvalueStatus = asset.statusOfValueForKey(statusKey,error: &error)            if status == AVkeyvalueStatus.Loaded{                let playerItem = AVPlayerItem(asset: asset)                self.player = AVPlayer(playerItem: playerItem)                self.sharedInstanceBool = true            } else {                self.errorMessage = error!.localizedDescription                print(error!)            }        })    })    NSNotificationCenter.defaultCenter().addobserverForname(        AVPlayerItemFailedtoplayToEndTimeNotification,object: nil,queue: nil,usingBlock: { notification in            print("Status: Failed to continue")            self.errorMessage = "Stream was interrupted"    })    print("Initializing new player")}func resetPlayer() {    errorMessage = ""    let asset: AVURLAsset = AVURLAsset(URL: NSURL(string: Globals.radioURL)!,error: &error)            if status == AVkeyvalueStatus.Loaded{                let playerItem = AVPlayerItem(asset: asset)                //playerItem.addobserver(self,forKeyPath: "status",options: NSkeyvalueObservingOptions.New,context: &ItemStatusContext)                self.player = AVPlayer(playerItem: playerItem)                self.sharedInstanceBool = true            } else {                self.errorMessage = error!.localizedDescription                print(error!)            }        })    })}func bufferFull() -> Bool {    return bufferAvailableSeconds() > 45.0}func bufferAvailableSeconds() -> NSTimeInterval {    // Check if there is a player instance    if ((player.currentItem) != nil) {        // Get current AVPlayerItem        let item: AVPlayerItem = player.currentItem!        if (item.status == AVPlayerItemStatus.Readytoplay) {            let timeRangeArray: NSArray = item.loadedTimeRanges            if timeRangeArray.count < 1 { return(CMTimeGetSeconds(kCMTimeInvalID)) }            let aTimeRange: CMTimeRange = timeRangeArray.objectAtIndex(0).CMTimeRangeValue            //let startTime = CMTimeGetSeconds(aTimeRange.end)            let loadedDuration = CMTimeGetSeconds(aTimeRange.duration)            return (NSTimeInterval)(loadedDuration);        }        else {            return(CMTimeGetSeconds(kCMTimeInvalID))        }    }     else {        return(CMTimeGetSeconds(kCMTimeInvalID))    }}func play() {    player.play()    isPlaying = true    print("Radio is \(isPlaying ? "" : "not ")playing")}func pause() {    player.pause()    isPlaying = false    print("Radio is \(isPlaying ? "" : "not ")playing")}func currentlyPlaying() -> Bool {    return isPlaying}}protocol sharedInstanceDelegate {func sharedInstanceChanged(newVal: Bool)}

RadioVIEwController:

import UIKitimport AVFoundationclass RadioVIEwController: UIVIEwController,errorMessageDelegate,sharedInstanceDelegate {// MARK: PropertIEsvar firstErrorSkip = truevar firstInstanceSkip = true@IBOutlet weak var ListenLabel: UILabel!@IBOutlet weak var radioSwitch: UIImageVIEw!@IBAction func back(sender: AnyObject) {    print("dismissing radio vIEw")    if let navigationController = self.navigationController    {        navigationController.popVIEwControllerAnimated(true)    }}@IBAction func switched(sender: AnyObject) {    toggle()}overrIDe func vIEwDIDLoad() {    super.vIEwDIDLoad()    do {        try AVAudioSession.sharedInstance().setcategory(AVAudioSessioncategoryPlayback)        print("AVAudioSession category Playback OK")        do {            try AVAudioSession.sharedInstance().setActive(true)            print("AVAudioSession is Active")        } catch let error as NSError {            print(error.localizedDescription)        }    } catch let error as NSError {        print(error.localizedDescription)    }    RadioPlayer.sharedInstance.errorDelegate = self    RadioPlayer.sharedInstance.instanceDelegate = self    if RadioPlayer.sharedInstance.currentlyPlaying() {        radioSwitch.image = UIImage(named: "Radio_Switch_Active")        ListenLabel.text = "Click to Pause Radio Stream:"    }}overrIDe func dIDReceiveMemoryWarning() {    super.dIDReceiveMemoryWarning()    // dispose of any resources that can be recreated.}func toggle() {    if RadioPlayer.sharedInstance.currentlyPlaying() {        pauseRadio()    } else {        playRadio()    }}func playRadio() {    firstErrorSkip = false    firstInstanceSkip = false    if RadioPlayer.sharedInstance.errorMessage != "" || RadioPlayer.sharedInstance.bufferFull() {        resetStream()    } else {        radioSwitch.image = UIImage(named: "Radio_Switch_Active")        ListenLabel.text = "Click to Pause Radio Stream:"        RadioPlayer.sharedInstance.play()    }}func pauseRadio() {    RadioPlayer.sharedInstance.pause()    radioSwitch.image = UIImage(named: "Radio_Switch_Inactive")    ListenLabel.text = "Click to Play Radio Stream:"}func resetStream() {    print("Reloading interrupted stream");    RadioPlayer.sharedInstance.resetPlayer()    //RadioPlayer.sharedInstance = RadioPlayer();    RadioPlayer.sharedInstance.errorDelegate = self    RadioPlayer.sharedInstance.instanceDelegate = self    if RadioPlayer.sharedInstance.bufferFull() {        radioSwitch.image = UIImage(named: "Radio_Switch_Active")        ListenLabel.text = "Click to Pause Radio Stream:"        RadioPlayer.sharedInstance.play()    } else {        playRadio()    }}func errorMessageChanged(newVal: String) {    if !firstErrorSkip {        print("Error changed to '\(newVal)'")        if RadioPlayer.sharedInstance.errorMessage != "" {            print("Showing Error Message")            let alertController = UIAlertController(Title: "Stream Failure",message: RadioPlayer.sharedInstance.errorMessage,preferredStyle: UIAlertControllerStyle.Alert)            alertController.addAction(UIAlertAction(Title: "dismiss",style: UIAlertActionStyle.Default,handler: nil))            self.presentVIEwController(alertController,animated: true,completion: nil)            pauseRadio()        }    } else {        print("SkipPing first init")        firstErrorSkip = false    }}func sharedInstanceChanged(newVal: Bool) {    if !firstInstanceSkip {    print("Detected New Instance")        if newVal {            RadioPlayer.sharedInstance.play()        }    } else {        firstInstanceSkip = false    }}}

希望这会有所帮助:)

总结

以上是内存溢出为你收集整理的如何在iOS中使用AVPlayer缓冲音频?全部内容,希望文章能够帮你解决如何在iOS中使用AVPlayer缓冲音频?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1075276.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存