Hi all,We are using AVPlayer to play our audio only HLS streams and are seeing what looks like a threading issue with the currentTime() method on AVPlayer vs the times reported by using the periodicTimeObserver.Here's the scenario:1. A class registers as a periodicTimeObserver using 0.1 seconds as the desired time interval.2. Lets say the current time (as reported to the periodic observer) reaches 8.8 seconds.3. On a separate thread, we have the player seek to the currentTime() + 2 seconds.4. Within the completion block of the call to seek, we read & report what the new currentTime() is5. While this is happening, you still listen to the periodicTimeObserver callbacks.6. You'll notice the time reported by the call to currentTime() within the seek completion block is actually AFTER the currentTime() as reported by the periodicTimeObserver.Here it is in code:let underlyingPlayer: AVQueuePlayer = ...
underlyingPlayer.seek(to: newPosition, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero, completionHandler: { [weak self] success in
let time = underlyingPlayer.currentTime
print("After seeking, the current time is \(time)")
completionHandler?(error, time)
})
// periodic time observer is set up as the following with an interval of 0.1 seconds
let underlyingTimeObservingQueue = DispatchQueue(label: "com.company.player.timeObserver.queue", qos: DispatchQoS.userInitiated)
let valueInterval = CMTimeMakeWithSeconds(interval, 1000)
return underlyingPlayer.addPeriodicTimeObserver(forInterval: valueInterval, queue: underlyingTimeObservingQueue) { time in
print("periodic time is \(CMTimeGetSeconds(time))")
return block(CMTimeGetSeconds(time))
}
}When you run this, here's the output we receive:periodicTime is 7.701181537periodicTime is 7.801130009periodicTime is 7.900316636periodicTime is 8.000758814periodicTime is 8.100601498periodicTime is 8.201145766periodicTime is 8.301150409periodicTime is 8.401138697periodicTime is 8.501144148periodicTime is 8.601161655periodicTime is 8.701154072periodicTime is 8.800160082After seeking, the current time is 10.88 <----------------- This is the result returned by the seek call's completion blockperiodicTime is 10.736309528periodicTime is 10.736393196periodicTime is 10.801075743periodicTime is 10.900429325periodicTime is 11.000907073periodicTime is 11.100982256periodicTime is 11.201173809periodicTime is 11.300147113periodicTime is 11.401182831periodicTime is 11.500769324periodicTime is 11.600593684periodicTime is 11.701193966periodicTime is 11.800258566periodicTime is 11.900176181periodicTime is 12.000423167This seems like a bug within AVPlayer, but wanted to check here before filing it.We couldn't really find any workarounds for this, but here's what we tried so far:1. Unregistering all periodicTimeObservers right before seeking, and adding them back in the seek completion handler2. Dispatch_sync the call to currentTime() within the seek method's completion blockHowever, none of these solutions fixed the problem.Does anyone have any ideas about what's going on?
Post
Replies
Boosts
Views
Activity
Hi,
I was looking around at the posts about AVAssetResourceLoaderDelegate and HLS audio only streams.
I've noticed that once I issue a redirect in the loader delegate, it is never called again...which prevents me from setting my own custom User-Agent header for the rest of the media, or my allowsCellularAccess settings on the urlRequest.
What is Apple's recommendation to actually do this properly?
Thanks
We're experimenting with a stream that has a large (10 minutes) clear portion in front of the protected section w/Fairplay.
We're noticing that AVPlayer/Safari trigger calls to fetch the license key even while it's playing the clear part, and once we provide the key, playback fails with:
name = AVPlayerItemFailedToPlayToEndTimeNotification, object = Optional(<AVPlayerItem: 0x281ff2800> I/NMU [No ID]), userInfo = Optional([AnyHashable("AVPlayerItemFailedToPlayToEndTimeErrorKey"): Error Domain=CoreMediaErrorDomain Code=-12894 "(null)"])
- name : "AVPlayerItemFailedToPlayToEndTimeNotification"
- object : <AVPlayerItem: 0x281ff2800> I/NMU [No ID]
▿ userInfo : 1 element
▿ 0 : 2 elements
▿ key : AnyHashable("AVPlayerItemFailedToPlayToEndTimeErrorKey")
- value : "AVPlayerItemFailedToPlayToEndTimeErrorKey"
- value : Error Domain=CoreMediaErrorDomain Code=-12894 "(null)"
It seems like AVPlayer is trying to decrypt the clear portion of the stream...and I'm wondering if it's because we've set up our manifest incorrectly.
Here it is:
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:20
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="clear-asset.mp4",BYTERANGE="885@0"
#EXT-X-DEFINE:NAME="path0",VALUE="clear-asset.mp4"
#EXTINF:9.98458,
#EXT-X-BYTERANGE:81088@885
{$path0}
#EXTINF:19.96916,
#EXT-X-BYTERANGE:159892@81973
{$path0}
#EXTINF:19.96916,
#EXT-X-BYTERANGE:160245@241865
{$path0}
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="secure-asset.mp4",BYTERANGE="788@0"
#EXT-X-DEFINE:NAME="path1",VALUE="secure-asset.mp4"
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://guid",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXTINF:19.96916,
#EXT-X-BYTERANGE:159928@5196150
{$path1}
#EXT-X-ENDLIST