Воспроизведение URL-адреса TuneIn Radio в прямом эфире iOS Swift

Я работаю над приложением, которое предназначено для воспроизведения радио с использованием URL-адресов TuneIn. В TuneIn в API есть HTTP-запрос на получение, который предоставляет JSON со всеми URL-адресами и их битрейтами.

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

вернется

{ "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 }] }

Мой первый подход состоял в том, чтобы настроить AVPlayer с одним из указанных URL-адресов, но он не воспроизводился.

Кроме того, если вы скопируете и вставите URL-адрес в браузер Chrome, он начнет загрузку файла, который будет длиться вечно.

Проверив с помощью wireshark, я, наконец, обнаружил, что потоковый URL-адрес отличается, и он предоставляется с заголовком при первом запросе файла.

Я знаю, что это было сделано на Android путем перехвата заголовков, но возможно ли сделать то же самое на iOS?

Я искал некоторые библиотеки, и MobileVLCKit кажется кандидатом, но не уверен, как я рискую, что мое приложение может быть отклонено.

Поскольку в настоящее время потоковое вещание очень популярно, могу ли я добиться этого «путем Apple»?

Спасибо


person Reimond Hill    schedule 11.10.2018    source источник


Ответы (1)


ДЛЯ ВСЕХ, кто хочет транслировать на TUNEIN

Оказывается, если вы настроите AVPlayer следующим образом:

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

    }

}

Он будет воспроизводиться, но вам нужно разрешить произвольные загрузки в info.plist.

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

И это сработало!

ДОПОЛНЕНИЕ

Я также обнаружил, что некоторые ссылки не воспроизводятся, особенно те, которые содержат файлы .pls (хотя URL-адрес остается прежним). И iOS, и Safari пытаются решить их, но возникает ошибка о несовместимости плагинов.

Я обнаружил, что если я делаю URL-запрос к URL-адресу, возвращаемые данные представляют собой список ссылок, разделенных разрывами строк.

Итак: класс My Connection Helper:

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

    }

}

И из класса вызывается функция:

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

РЕЗУЛЬТАТ строковых данных:

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
person Reimond Hill    schedule 15.10.2018