Fix(ios): fix real time issue when fast zapping (#3582)

* fix(ios): fix real time issue when doing fast zapping

* fix(ios): fix delay implementation (timing was not applied correctly)

* chore: fix random crash in sample

* chore: fix linter
This commit is contained in:
Olivier Bouillet 2024-03-14 11:46:45 +01:00 committed by GitHub
parent f4cce2ecdb
commit 429fddf3b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 10 deletions

View File

@ -693,6 +693,9 @@ class VideoPlayer extends Component {
});
}}>
{this.state.audioTracks.map(track => {
if (!track) {
return;
}
return (
<Picker.Item
label={track.language}
@ -720,13 +723,18 @@ class VideoPlayer extends Component {
});
}}>
<Picker.Item label={'none'} value={'none'} key={'none'} />
{this.state.textTracks.map(track => (
{this.state.textTracks.map(track => {
if (!track) {
return;
}
return (
<Picker.Item
label={track.language}
value={track.language}
key={track.language}
/>
))}
);
})}
</Picker>
)}
</View>

View File

@ -364,7 +364,7 @@ enum RCTVideoUtils {
static func delay(seconds: Int = 0) -> Promise<Void> {
return Promise<Void>(on: .global()) { fulfill, _ in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(seconds)) / Double(NSEC_PER_SEC)) {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(seconds)) {
fulfill(())
}
}

View File

@ -300,14 +300,38 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
}
}
var isSetSourceOngoing = false
var nextSource: NSDictionary?
func applyNextSource() {
if self.nextSource != nil {
DebugLog("apply next source")
self.isSetSourceOngoing = false
let nextSrc = self.nextSource
self.nextSource = nil
self.setSrc(nextSrc)
}
}
// MARK: - Player and source
@objc
func setSrc(_ source: NSDictionary!) {
if self.isSetSourceOngoing || self.nextSource != nil {
DebugLog("setSrc buffer request")
self._player?.replaceCurrentItem(with: nil)
nextSource = source
return
}
self.isSetSourceOngoing = true
let dispatchClosure = {
self._source = VideoSource(source)
if self._source?.uri == nil || self._source?.uri == "" {
self._player?.replaceCurrentItem(with: nil)
self.isSetSourceOngoing = false
self.applyNextSource()
DebugLog("setSrc Stopping playback")
return
}
self.removePlayerLayer()
@ -321,9 +345,13 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
guard let self else { throw NSError(domain: "", code: 0, userInfo: nil) }
guard let source = self._source else {
DebugLog("The source not exist")
self.isSetSourceOngoing = false
self.applyNextSource()
throw NSError(domain: "", code: 0, userInfo: nil)
}
if let uri = source.uri, uri.starts(with: "ph://") {
self.isSetSourceOngoing = false
self.applyNextSource()
return Promise {
RCTVideoUtils.preparePHAsset(uri: uri).then { asset in
return self.playerItemPrepareText(asset: asset, assetOptions: nil, uri: source.uri ?? "")
@ -334,6 +362,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
let asset = assetResult.asset,
let assetOptions = assetResult.assetOptions else {
DebugLog("Could not find video URL in source '\(String(describing: self._source))'")
self.isSetSourceOngoing = false
self.applyNextSource()
throw NSError(domain: "", code: 0, userInfo: nil)
}
@ -361,7 +391,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
return self.playerItemPrepareText(asset: asset, assetOptions: assetOptions, uri: source.uri ?? "")
}.then { [weak self] (playerItem: AVPlayerItem!) in
guard let self else { throw NSError(domain: "", code: 0, userInfo: nil) }
if !self.isSetSourceOngoing {
DebugLog("setSrc has been canceled last step")
return
}
self._player?.pause()
self._playerItem = playerItem
self._playerObserver.playerItem = self._playerItem
@ -402,8 +435,16 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
"drm": self._drm?.json ?? NSNull(),
"target": self.reactTag,
])
}.catch { _ in }
self.isSetSourceOngoing = false
self.applyNextSource()
}.catch { error in
DebugLog("An error occurred: \(error.localizedDescription)")
self.onVideoError?(["error": error.localizedDescription])
self.isSetSourceOngoing = false
self.applyNextSource()
}
self._videoLoadStarted = true
self.applyNextSource()
}
DispatchQueue.global(qos: .default).async(execute: dispatchClosure)
}