Playing a live TuneIn Radio URL iOS Swift

若如初见. 提交于 2019-12-24 08:06:08

问题


I am working on an app which is intended to play life radio by using TuneIn URLs. In TuneIn, there is an http get request in the API which provides a JSON with all the URL and its bitrates.

So http://opml.radiotime.com/Tune.ashx?id=s150147&formats=aac,mp3&render=json

will return

{ "head": { "status": "200"}, "body": [
 { "element" : "audio", 
"url": "http://player.absoluteradio.co.uk/tunein.php?i=a664.aac",
"reliability": 95,
"bitrate": 64,
"media_type": "aac",
"position": 0,
"player_width": 529,
"player_height": 716,
"guide_id": "e89279187",
"is_direct": false }, { "element" : "audio", 
"url": "http://player.absoluteradio.co.uk/tunein.php?i=a6low.mp3",
"reliability": 78,
"bitrate": 48,
"media_type": "mp3",
"position": 0,
"player_width": 529,
"player_height": 716,
"guide_id": "e89279188",
"is_direct": false }, { "element" : "audio", 
"url": "http://player.absoluteradio.co.uk/tunein.php?i=a624.aac",
"reliability": 29,
"bitrate": 24,
"media_type": "aac",
"position": 0,
"player_width": 529,
"player_height": 716,
"guide_id": "e89279186",
"is_direct": false }] }

My first approach was to setup an AVPlayer with one of the URLs given but it didn't play.

Furthermore, If you copy and paste a URL in a chrome browser it starts downloading a file that takes forever.

Inspecting with wireshark, I finally found that the streaming URL is a different one and it is provided with the Header on the first time you request a file.

I know that has been done on android by intercepting the headers but, Is is possible to do the same on iOS?

I have been looking some libraries and MobileVLCKit seems a candidate but not sure how I am risking the possibility of my app getting rejected.

Since, streaming is very popular action nowadays, Can I achieve that in an "Apple way"

Thank you


回答1:


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


来源:https://stackoverflow.com/questions/52754263/playing-a-live-tunein-radio-url-ios-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!