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
Implement Protocol Through Extension
Swift 4: Validating Credit Card Expiration Date
Split Paragraphs into Sentences
Scrolling Delegate in Tableview
Find Out When Uikeyboard.Frame Intersects with Other Frame
Swift MAC App, Run Terminal Command Without Knowing the Path (So It Looks in Every Path in $Path)
Swift 'Unable to Dequeue a Cell with Identifier Intervalcellidentifier
Button State Activates on Wrong Cells
Tvos Textfield Transparent Background
Swift: Generic Overloads, Definition of "More Specialized"
Creating a Subclass of Skshapenode
Swift Firestore Search for Users
Skscene Becomes Unresponsive While Being Idle
Storing Array of Custom Objects in Userdefaults