tvOS 18下HLS直播流章节封面图在AVPlayer中闪烁的问题求助
tvOS 18下HLS直播流章节封面图在AVPlayer中闪烁的问题求助
我最近遇到了一个棘手的问题:在tvOS 18的模拟器和真实Apple TV设备上,用AVPlayer播放带章节封面图的HLS直播流时,章节的封面图会持续闪烁。但如果完全移除封面图,播放就完全正常,没有任何视觉问题。更奇怪的是,同样的逻辑在tvOS 17上是正常工作的,到tvOS 18就出问题了。
实现细节
- 使用AVPlayer播放HLS直播流
- 章节标记的时间戳和标题配置都没问题
- 封面图是通过网络加载的(没办法打包到APP里),格式为PNG
- 就算等图片完全加载完成后再播放,闪烁问题依然存在
- 这个问题只在Apple TV/tvOS上出现,而且仅针对直播流——用同样的图片做VOD内容的章节封面完全没问题
示例代码
我写了一个最小复现的示例,先从网络加载几张图片,然后把它们作为直播流不同章节的封面:
import SwiftUI import AVKit struct Chapter: Identifiable { let id = UUID() let title: String let seconds: Double var artworkData: Data? } class ChaptersLoader: ObservableObject { @Published var chapters: [Chapter] = [] @Published var ready = false let baseChapters = [ ("Intro", 0.0), ("Chapter 1", 60.0), ("Chapter 2", 120.0), ("Chapter 3", 180.0) ] func load() { var loaded: [Chapter] = [] let group = DispatchGroup() for (title, seconds) in baseChapters { group.enter() let url = URL(string: "https://cataas.com/cat")! URLSession.shared.dataTask(with: url) { data, _, _ in var chapter = Chapter(title: title, seconds: seconds, artworkData: nil) if let data = data { chapter.artworkData = data } loaded.append(chapter) group.leave() }.resume() } group.notify(queue: .main) { loaded.sort { $0.seconds < $1.seconds } self.chapters = loaded self.ready = true } } } struct AVPlayerViewControllerRepresentable: UIViewControllerRepresentable { let streamURL: URL let chapters: [Chapter] func makeUIViewController(context: Context) -> AVPlayerViewController { let item = AVPlayerItem(url: streamURL) let groups = chapters.map { chapter -> AVTimedMetadataGroup in let titleItem = AVMutableMetadataItem() titleItem.identifier = .commonIdentifierTitle titleItem.value = chapter.title as NSString titleItem.extendedLanguageTag = "und" var items: [AVMetadataItem] = [titleItem] if let data = chapter.artworkData { let artworkItem = AVMutableMetadataItem() artworkItem.identifier = .commonIdentifierArtwork artworkItem.dataType = kCMMetadataBaseDataType_PNG as String artworkItem.value = data as NSData artworkItem.extendedLanguageTag = "und" items.append(artworkItem) } let time = CMTime(seconds: chapter.seconds, preferredTimescale: 1) let range = CMTimeRange(start: time, duration: CMTime(seconds: 10, preferredTimescale: 1)) return AVTimedMetadataGroup(items: items, timeRange: range) } let navGroup = AVNavigationMarkersGroup(title: "Chapters", timedNavigationMarkers: groups) item.navigationMarkerGroups = [navGroup] let player = AVPlayer(playerItem: item) let controller = AVPlayerViewController() controller.player = player player.play() return controller } func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {} } struct ContentView: View { @StateObject var loader = ChaptersLoader() let streamURL = URL(string: "https://ireplay.tv/test/blender.m3u8")! var body: some View { Group { if loader.ready { AVPlayerViewControllerRepresentable(streamURL: streamURL, chapters: loader.chapters) .edgesIgnoringSafeArea(.all) } else { ProgressView("Loading cat artwork...") .onAppear { loader.load() } } } } } @main struct YourProjectNameApp: App { var body: some Scene { WindowGroup { ContentView() } } }
我已经尝试过的方法
- 播放前预加载所有图片
- 更换不同的图片格式和尺寸
- 对图片进行缓存
但这些方法都没能解决闪烁问题。
我的疑问
这是tvOS 18中直播流章节封面图的已知限制吗?有没有人遇到过类似问题,能提供解决方案或绕过方法?或者我的代码里有没有遗漏什么细节?
内容来源于stack exchange
相关产品推荐
相关产品推荐

