In an iOS application, I want to generate preview thumbnails when seeking in an HLS stream with I-frames.
I'm using AVAssetImageGenerator, and it works well across all segments of the HLS stream except for the last one. Once it reaches the final segment, it no longer generates images for any segment.
The following example uses a test HLS stream from Apple:
import AVKit
import Combine
import SwiftUI
let videoURL = URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8")!
final class ViewModel: ObservableObject {
@Published var duration: Double = 0
@Published var position: Double = 0
@Published var image: UIImage?
private let asset: AVAsset
private let generator: AVAssetImageGenerator
private var subscriber: AnyCancellable?
init() {
asset = AVAsset(url: videoURL)
generator = AVAssetImageGenerator(asset: asset)
subscriber = $position.sink { [weak self] in
self?.generateImage(for: CMTime(seconds: $0, preferredTimescale: 1000))
}
Task {
let duration = try! await asset.load(.duration)
await MainActor.run {
self.duration = CMTimeGetSeconds(duration)
}
}
}
private func generateImage(for time: CMTime) {
Task {
do {
let result = try await generator.image(at: time)
await MainActor.run {
self.image = UIImage(cgImage: result.image)
}
} catch {
print(error)
}
}
}
}
struct ContentView: View {
@StateObject private var model = ViewModel()
var body: some View {
VStack {
if let image = model.image {
Image(uiImage: image)
}
Slider(value: $model.position, in: .init(uncheckedBounds: (lower: 0, upper: model.duration)))
}
.padding()
}
}
This issue occurs only for the last segment of the stream; for all previous segments, it works without any issues.
Has anyone encountered a similar issue?