iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何在iOS中使用AVPlayer缓冲音频?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我想从互联网播放流音频.我编写了播放流的代码,但它没有任何缓冲区,所以如果信号弱则应用程序停止播放音频.这是我的代码

import UIKit
import AVFoundation
import MediaPlayer
import AudioToolBox

class 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是类似的吗?

解决方法

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

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

protocol errormessageDelegate {
func errormessageChanged(newVal: String)
}

类:

import Foundation
import AVFoundation
import UIKit

class RadioPlayer : NSObject {

static let sharedInstance = RadioPlayer()
var instanceDelegate:sharedInstanceDelegate? = nil
var 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 = false

var errorDelegate:errormessageDelegate? = nil
var 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 UIKit
import AVFoundation

class RadioViewController: UIViewController,errormessageDelegate,sharedInstanceDelegate {

// MARK: Properties

var firstErrorSkip = true
var 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缓冲音频?所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。