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:
parent
f4cce2ecdb
commit
429fddf3b0
@ -693,6 +693,9 @@ class VideoPlayer extends Component {
|
|||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
{this.state.audioTracks.map(track => {
|
{this.state.audioTracks.map(track => {
|
||||||
|
if (!track) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Picker.Item
|
<Picker.Item
|
||||||
label={track.language}
|
label={track.language}
|
||||||
@ -720,13 +723,18 @@ class VideoPlayer extends Component {
|
|||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<Picker.Item label={'none'} value={'none'} key={'none'} />
|
<Picker.Item label={'none'} value={'none'} key={'none'} />
|
||||||
{this.state.textTracks.map(track => (
|
{this.state.textTracks.map(track => {
|
||||||
<Picker.Item
|
if (!track) {
|
||||||
label={track.language}
|
return;
|
||||||
value={track.language}
|
}
|
||||||
key={track.language}
|
return (
|
||||||
/>
|
<Picker.Item
|
||||||
))}
|
label={track.language}
|
||||||
|
value={track.language}
|
||||||
|
key={track.language}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Picker>
|
</Picker>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
@ -364,7 +364,7 @@ enum RCTVideoUtils {
|
|||||||
|
|
||||||
static func delay(seconds: Int = 0) -> Promise<Void> {
|
static func delay(seconds: Int = 0) -> Promise<Void> {
|
||||||
return Promise<Void>(on: .global()) { fulfill, _ in
|
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(())
|
fulfill(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
// MARK: - Player and source
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
func setSrc(_ source: NSDictionary!) {
|
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 = {
|
let dispatchClosure = {
|
||||||
self._source = VideoSource(source)
|
self._source = VideoSource(source)
|
||||||
if self._source?.uri == nil || self._source?.uri == "" {
|
if self._source?.uri == nil || self._source?.uri == "" {
|
||||||
self._player?.replaceCurrentItem(with: nil)
|
self._player?.replaceCurrentItem(with: nil)
|
||||||
|
self.isSetSourceOngoing = false
|
||||||
|
self.applyNextSource()
|
||||||
|
DebugLog("setSrc Stopping playback")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.removePlayerLayer()
|
self.removePlayerLayer()
|
||||||
@ -321,9 +345,13 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
guard let self else { throw NSError(domain: "", code: 0, userInfo: nil) }
|
guard let self else { throw NSError(domain: "", code: 0, userInfo: nil) }
|
||||||
guard let source = self._source else {
|
guard let source = self._source else {
|
||||||
DebugLog("The source not exist")
|
DebugLog("The source not exist")
|
||||||
|
self.isSetSourceOngoing = false
|
||||||
|
self.applyNextSource()
|
||||||
throw NSError(domain: "", code: 0, userInfo: nil)
|
throw NSError(domain: "", code: 0, userInfo: nil)
|
||||||
}
|
}
|
||||||
if let uri = source.uri, uri.starts(with: "ph://") {
|
if let uri = source.uri, uri.starts(with: "ph://") {
|
||||||
|
self.isSetSourceOngoing = false
|
||||||
|
self.applyNextSource()
|
||||||
return Promise {
|
return Promise {
|
||||||
RCTVideoUtils.preparePHAsset(uri: uri).then { asset in
|
RCTVideoUtils.preparePHAsset(uri: uri).then { asset in
|
||||||
return self.playerItemPrepareText(asset: asset, assetOptions: nil, uri: source.uri ?? "")
|
return self.playerItemPrepareText(asset: asset, assetOptions: nil, uri: source.uri ?? "")
|
||||||
@ -334,6 +362,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
let asset = assetResult.asset,
|
let asset = assetResult.asset,
|
||||||
let assetOptions = assetResult.assetOptions else {
|
let assetOptions = assetResult.assetOptions else {
|
||||||
DebugLog("Could not find video URL in source '\(String(describing: self._source))'")
|
DebugLog("Could not find video URL in source '\(String(describing: self._source))'")
|
||||||
|
self.isSetSourceOngoing = false
|
||||||
|
self.applyNextSource()
|
||||||
throw NSError(domain: "", code: 0, userInfo: nil)
|
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 ?? "")
|
return self.playerItemPrepareText(asset: asset, assetOptions: assetOptions, uri: source.uri ?? "")
|
||||||
}.then { [weak self] (playerItem: AVPlayerItem!) in
|
}.then { [weak self] (playerItem: AVPlayerItem!) in
|
||||||
guard let self else { throw NSError(domain: "", code: 0, userInfo: nil) }
|
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._player?.pause()
|
||||||
self._playerItem = playerItem
|
self._playerItem = playerItem
|
||||||
self._playerObserver.playerItem = self._playerItem
|
self._playerObserver.playerItem = self._playerItem
|
||||||
@ -402,8 +435,16 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
"drm": self._drm?.json ?? NSNull(),
|
"drm": self._drm?.json ?? NSNull(),
|
||||||
"target": self.reactTag,
|
"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._videoLoadStarted = true
|
||||||
|
self.applyNextSource()
|
||||||
}
|
}
|
||||||
DispatchQueue.global(qos: .default).async(execute: dispatchClosure)
|
DispatchQueue.global(qos: .default).async(execute: dispatchClosure)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user