Swift Radio Streaming Avplayer

Swift Radio Streaming AVPlayer

I created a radio player with swift, but i used MediaPlayer framework to play.

var radioPlayer = MPMoviePlayerController(contentURL: "YOUR NSURL OBJECT WITH YOUR CUSTOM URL TO STREAM HERE");
radioPlayer.view.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
radioPlayer.view.sizeToFit()
radioPlayer.movieSourceType = MPMovieSourceType.Streaming
radioPlayer.fullscreen = false;
radioPlayer.shouldAutoplay = true;
radioPlayer.prepareToPlay()
radioPlayer.play()
radioPlayer.controlStyle = MPMovieControlStyle.None;

If you need listen metada from stream you need observer this notification MPMoviePlayerTimedMetadataUpdatedNotification

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("metadataUpdated:"), name:MPMoviePlayerTimedMetadataUpdatedNotification, object: nil);

func metadataUpdated(n:NSNotification)
{
if(radioPlayer.timedMetadata != nil && radioPlayer.timedMetadata.count > 0)
{
let firstMeta:MPTimedMetadata = radioPlayer.timedMetadata.first as! MPTimedMetadata;
let data:String = firstMeta.value as! String;
println(data); //your metadata here
}
}

With this you will can make your radio player, and because this radio i worked, i made one lib to get information about music in Itunes, well, this lib is open and because this I just want one favor, if you find problem, bug our better solution, fix and push to all.

ItunesSearch Lib in GitHub

How to implement a HLS for Radio Live Streaming service in Swift

I have tried to play the url with different approaches but I found out something that made AVPlayer work but still don't know what happens behind the scenes...

My first approach was to initialise the AVPlayer and set the AVURLAsset resource loader delegate but, since a Reserved/Standard url scheme doesn't trigger the delegate, I was into a dead end...

Secondly and after implementing the AVPlayer like that:

class ViewController: UIViewController, AVAssetResourceLoaderDelegate {

let urlFile = URL(string:"http://player.absoluteradio.co.uk/tunein.php?i=a664.aac")!

private var avPlayer:AVPlayer!
private var avAudioSession:AVAudioSession = AVAudioSession.sharedInstance()

override func viewDidLoad() {
super.viewDidLoad()

try! avAudioSession.setCategory(.playback, mode: .default, options: [])
try! avAudioSession.setActive(true)

let audioURLAsset = AVURLAsset(url: urlFile)
//audioURLAsset.resourceLoader.setDelegate(self, queue:DispatchQueue.init(label: "MY QUEUE"))
avPlayer = AVPlayer(playerItem: AVPlayerItem(asset: audioURLAsset))

avPlayer.play()

}

}

I have allowed Arbitrary loads in my info.plist

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

And It worked!

Playing a live TuneIn Radio URL iOS Swift

FOR ALL Who want to stream fro TUNEIN

Turns out that if you setup AVPlayer like that:

class ViewController: UIViewController, AVAssetResourceLoaderDelegate {

let urlFile = URL(string:"http://opml.radiotime.com/Tune.ashx?id=s150147&formats=aac,mp3")!

private var avPlayer:AVPlayer!
private var avAudioSession:AVAudioSession = AVAudioSession.sharedInstance()

override func viewDidLoad() {
super.viewDidLoad()

try! avAudioSession.setCategory(.playback, mode: .default, options: [])
try! avAudioSession.setActive(true)

let audioURLAsset = AVURLAsset(url: urlFile)
//audioURLAsset.resourceLoader.setDelegate(self, queue:DispatchQueue.init(label: "MY QUEUE"))
avPlayer = AVPlayer(playerItem: AVPlayerItem(asset: audioURLAsset))

avPlayer.play()

}

}

It will play but you need to allow Arbitrary loads in the info.plist

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

And It worked!

ADDITION

I have also find out that some of the links are not playable, specially the ones that contains .pls files (URL remains the same though). Both iOS and safari try to resolved them but there is an error about plugin incompatibility.

I found out that if I make a URL Request to the URL, the data back is a list of links separated by line brakes.

So:
My Connection Helper class:

class URLConnectionHelper: NSObject {

static func getResponse(fromURL url:URL?)->Data?{

guard let url = url else{ return nil }

var result:Data? = nil
let semaphore = DispatchSemaphore(value: 0)

URLSession.shared.dataTask(with: url) { (data, response, error) in

//guard let data = data else{ return nil}
result = data
semaphore.signal()

}.resume()

semaphore.wait()

return result

}

}

And from the class is calling the function:

guard let dataRadioItem = URLConnectionHelper.getResponse(fromURL: urlFile) else {return}

var urlArray = [URL]()
if let stringData = String(data: dataRadioItem, encoding: String.Encoding.utf8){
print("String Data: \(stringData)")

stringData.enumerateLines { (line, _) -> () in
if let urlLine = URL(string: line){
print("added = \(line)")
urlArray.append(urlLine)
}

}

}

if urlArray.count > 0{
urlFile = urlArray.first!
}

RESULT of String Data:

String Data: http://player.absoluteradio.co.uk/tunein.php?i=a664.aac
http://player.absoluteradio.co.uk/tunein.php?i=a6.mp3
http://player.absoluteradio.co.uk/tunein.php?i=a6low.mp3
http://player.absoluteradio.co.uk/tunein.php?i=a624.aac

Audio live streaming Swift

Turned out that i missed this :

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


Related Topics



Leave a reply



Submit