1 Commits

Author SHA1 Message Date
69a9159a43 Load video duration asynchronously
Some checks failed
Build Android / Build Android Example App (pull_request) Has been cancelled
Build Android / Build Android Example App Without Ads (pull_request) Has been cancelled
Build iOS / Build iOS Example App (pull_request) Has been cancelled
Build iOS / Build iOS Example App With Ads (pull_request) Has been cancelled
Build iOS / Build iOS Example App With Caching (pull_request) Has been cancelled
Check Android / Kotlin-Lint (pull_request) Has been cancelled
Check CLang / CLang-Format (pull_request) Has been cancelled
Check iOS / Swift-Lint (pull_request) Has been cancelled
Check iOS / Swift-Format (pull_request) Has been cancelled
Check JS / Check TS (tsc) (pull_request) Has been cancelled
Check JS / Lint JS (eslint, prettier) (pull_request) Has been cancelled
Test Docs build / build-docs (pull_request) Has been cancelled
2026-07-23 13:20:28 -07:00
2 changed files with 22 additions and 2 deletions

View File

@@ -34,6 +34,22 @@ enum RCTVideoAssetsUtils {
#endif #endif
} }
} }
static func getDuration(asset: AVAsset) async -> CMTime? {
if #available(iOS 15, tvOS 15, visionOS 1.0, *) {
return try? await asset.load(.duration)
} else {
#if !os(visionOS)
return await withCheckedContinuation { continuation in
asset.loadValuesAsynchronously(forKeys: ["duration"]) {
var error: NSError?
let status = asset.statusOfValue(forKey: "duration", error: &error)
continuation.resume(returning: status == .loaded ? asset.duration : nil)
}
}
#endif
}
}
} }
// MARK: - RCTVideoUtils // MARK: - RCTVideoUtils

View File

@@ -1420,7 +1420,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
} }
if onVideoLoad != nil, self._videoLoadStarted { if onVideoLoad != nil, self._videoLoadStarted {
var duration = Float(CMTimeGetSeconds(_playerItem.asset.duration)) let assetDuration = await RCTVideoAssetsUtils.getDuration(asset: _playerItem.asset)
guard self._playerItem === _playerItem,
self._source?.json === source.json else { return }
var duration = Float(CMTimeGetSeconds(assetDuration ?? .invalid))
if duration.isNaN || duration == 0 { if duration.isNaN || duration == 0 {
// This is a safety check for live video. // This is a safety check for live video.
@@ -1449,6 +1452,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player) let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player)
let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player) let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player)
guard self._playerItem === _playerItem,
self._source?.json === source.json else { return }
self.onVideoLoad?(["duration": NSNumber(value: duration), self.onVideoLoad?(["duration": NSNumber(value: duration),
"currentTime": NSNumber(value: Float(CMTimeGetSeconds(_playerItem.currentTime()))), "currentTime": NSNumber(value: Float(CMTimeGetSeconds(_playerItem.currentTime()))),
"canPlayReverse": NSNumber(value: _playerItem.canPlayReverse), "canPlayReverse": NSNumber(value: _playerItem.canPlayReverse),
@@ -1699,4 +1704,3 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc @objc
func setOnClick(_: Any) {} func setOnClick(_: Any) {}
} }