helloB
helloB

Reputation: 3582

Play audio while downloading without downloading file twice?

I would like to write an iOS app that plays an audio file as soon as there is enough data while continuing to download. It seems that you can either download and play when the download is finishing (Using NSURLProtocol to implement play while downloading for AVPlayer on iOS) or continuously stream without getting to save a file (Playing audio file while I download it). Is there any way to download and play at the same time without downloading two copies of the file?

Upvotes: 4

Views: 1807

Answers (2)

Marwan Alqadi
Marwan Alqadi

Reputation: 855

here you can use below functions without download (Streaming)

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){_ 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)
        }
    }
}

Upvotes: 0

Rajat
Rajat

Reputation: 11127

You can do that with the help of AVAssetResourceLoader and AVPlayer

Here is the link of the tutorial

http://leshkoapps.com/wordpress/audio-streaming-and-caching-in-ios-using-avassetresourceloader-and-avplayer/

And here is the Github repo for that

https://github.com/leshkoapps/AVAssetResourceLoader

Upvotes: 3

Related Questions