Я оставляю здесь свой ответ на случай, если кому-то еще это понадобится.После исследования, проб и ошибок я наконец-то нашел способ заставить AVPlayer работать с NGINX rtmp hls.
Основная причина этого - неправильные метаданные видеофрагментов на сервере.Мы должны найти способ исправить это.
Это моя команда для вывода видео с моего macbook, типичная:
ffmpeg -f avfoundation -framerate 30 -i "0:0" -f flv -s 360x240 -vcodec libx264 -c:a aac -async 1 -vsync 1 -preset slower rtmp://127.0.0.1/live/xyz
На стороне сервера я настраиваю базовый RTMP NginxHLS на Ubuntu 18.10, который можно узнать, как в Google.Обратите внимание, что я перекомпилирую последнюю версию ffmpeg с помощью fdk_aac.
В RTMP есть 2 приложения: одно для приема в восходящем направлении, а другое для транскодирования HLS, что также типично.
Чтобы устранить проблему с метаданными, я настроилКоманда транскодирования ffmpeg с базовым профилем, добавив: -profile:v baseline -level 3.0
.Это приведет к ошибке из-за неправильного формата цвета, поэтому я также добавил: -vf "scale=480:trunc(ow/a/2)*2,format=yuv420p"
.
Наконец, моя конфигурация nginx, которая работает: https://gist.github.com/chung-nguyen/d88e73e3cc8788878f5ffb8c232b4729
И мой код AVPlayer в swift:
let videoURL = URL(string: "http://blogchange.live/hls/xyz_low/index.m3u8")
let playerItem = AVPlayerItem(url: videoURL!)
let adID = AVMetadataItem.identifier(forKey: "X-TITLE", keySpace: .hlsDateRange)
let metadataCollector = AVPlayerItemMetadataCollector(identifiers: [adID!.rawValue], classifyingLabels: nil)
metadataCollector.setDelegate(self, queue: DispatchQueue.main)
playerItem.add(metadataCollector)
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
self.player = player
player.play()