Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(ios): add early returns #3741

Merged
merged 3 commits into from
May 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 50 additions & 32 deletions ios/Video/RCTVideo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
// MARK: - Progress

func sendProgressUpdate() {
#if !USE_GOOGLE_IMA
// If we dont use Ads and onVideoProgress is not defined we dont need to run this code
guard onVideoProgress != nil else { return }
#endif

KrzysztofMoch marked this conversation as resolved.
Show resolved Hide resolved
if let video = _player?.currentItem,
video == nil || video.status != AVPlayerItem.Status.readyToPlay {
return
Expand Down Expand Up @@ -1300,6 +1305,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
// When timeMetadata is read the event onTimedMetadata is triggered
func handleTimeMetadataChange(timedMetadata: [AVMetadataItem]) {
guard onTimedMetadata != nil else { return }

var metadata: [[String: String?]?] = []
for item in timedMetadata {
let value = item.value as? String
Expand Down Expand Up @@ -1331,32 +1337,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

func handleReadyToPlay() {
guard let _playerItem else { return }
var duration = Float(CMTimeGetSeconds(_playerItem.asset.duration))

if duration.isNaN || duration == 0 {
// This is a safety check for live video.
// AVPlayer report a 0 duration
duration = RCTVideoUtils.calculateSeekableDuration(_player).floatValue
if duration.isNaN {
duration = 0
}
}

var width: Float = 0
var height: Float = 0
var orientation = "undefined"

Task {
let tracks = await RCTVideoAssetsUtils.getTracks(asset: _playerItem.asset, withMediaType: .video)
if let videoTrack = tracks?.first {
width = Float(videoTrack.naturalSize.width)
height = Float(videoTrack.naturalSize.height)
} else if _playerItem.presentationSize.height != 0.0 {
width = Float(_playerItem.presentationSize.width)
height = Float(_playerItem.presentationSize.height)
}
orientation = width > height ? "landscape" : width == height ? "square" : "portrait"

if self._pendingSeek {
self.setSeek([
"time": NSNumber(value: self._pendingSeekTime),
Expand All @@ -1373,7 +1355,32 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
self._startPosition = -1
}

if self._videoLoadStarted {
if onVideoLoad != nil, self._videoLoadStarted {
var duration = Float(CMTimeGetSeconds(_playerItem.asset.duration))

if duration.isNaN || duration == 0 {
// This is a safety check for live video.
// AVPlayer report a 0 duration
duration = RCTVideoUtils.calculateSeekableDuration(_player).floatValue
if duration.isNaN {
duration = 0
}
}

var width: Float = 0
var height: Float = 0
var orientation = "undefined"

let tracks = await RCTVideoAssetsUtils.getTracks(asset: _playerItem.asset, withMediaType: .video)
if let videoTrack = tracks?.first {
width = Float(videoTrack.naturalSize.width)
height = Float(videoTrack.naturalSize.height)
} else if _playerItem.presentationSize.height != 0.0 {
width = Float(_playerItem.presentationSize.width)
height = Float(_playerItem.presentationSize.height)
}
orientation = width > height ? "landscape" : width == height ? "square" : "portrait"

let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player)
let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player)
self.onVideoLoad?(["duration": NSNumber(value: duration),
Expand Down Expand Up @@ -1463,7 +1470,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
}

func handleVolumeChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) {
guard let _player else { return }
guard let _player, onVolumeChange != nil else { return }
KrzysztofMoch marked this conversation as resolved.
Show resolved Hide resolved

if player.rate == change.oldValue && change.oldValue != nil {
return
Expand All @@ -1475,7 +1482,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

func handleExternalPlaybackActiveChange(player _: AVPlayer, change _: NSKeyValueObservedChange<Bool>) {
#if !os(visionOS)
guard let _player else { return }
guard let _player, onVideoExternalPlaybackChange != nil else { return }
KrzysztofMoch marked this conversation as resolved.
Show resolved Hide resolved
onVideoExternalPlaybackChange?(["isExternalPlaybackActive": NSNumber(value: _player.isExternalPlaybackActive),
"target": reactTag as Any])
#endif
Expand Down Expand Up @@ -1514,6 +1521,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

@objc
func handleDidFailToFinishPlaying(notification: NSNotification!) {
guard onVideoError != nil else { return }

let error: NSError! = notification.userInfo?[AVPlayerItemFailedToPlayToEndTimeErrorKey] as? NSError
onVideoError?(
[
Expand Down Expand Up @@ -1563,6 +1572,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc
func handleAVPlayerAccess(notification: NSNotification!) {
guard onVideoBandwidthUpdate != nil else { return }

guard let accessLog = (notification.object as? AVPlayerItem)?.accessLog() else {
return
}
Expand All @@ -1572,16 +1582,24 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
}

func handleTracksChange(playerItem _: AVPlayerItem, change _: NSKeyValueObservedChange<[AVPlayerItemTrack]>) {
Task {
let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player)
let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player)
if onTextTracks != nil {
Task {
let textTracks = await RCTVideoUtils.getTextTrackInfo(self._player)
self.onTextTracks?(["textTracks": self._textTracks?.compactMap { $0.json } ?? textTracks.compactMap(\.json)])
}
}

self.onTextTracks?(["textTracks": self._textTracks?.compactMap { $0.json } ?? textTracks.compactMap(\.json)])
self.onAudioTracks?(["audioTracks": audioTracks])
if onAudioTracks != nil {
Task {
let audioTracks = await RCTVideoUtils.getAudioTrackInfo(self._player)
self.onAudioTracks?(["audioTracks": audioTracks])
}
}
}

func handleLegibleOutput(strings: [NSAttributedString]) {
guard onTextTrackDataChanged != nil else { return }

if let subtitles = strings.first {
self.onTextTrackDataChanged?(["subtitleTracks": subtitles.string])
}
Expand Down
Loading