feat(ios): add onBandwidthUpdate event (#3331)

* feat(ios): add onBandwidthUpdate event
This commit is contained in:
Krzysztof Moch 2023-11-08 22:06:29 +01:00 committed by GitHub
parent 8fbdc28a73
commit 9054db35d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 30 deletions

View File

@ -86,14 +86,27 @@ Payload:
Property | Type | Description Property | Type | Description
--- | --- | --- --- | --- | ---
bitrate | number | The estimated bitrate in bits/sec bitrate | number | The estimated bitrate in bits/sec
width | number | The width of the video (android only)
height | number | The height of the video (android only)
trackId | string | The track ID of the video track (android only)
Example: Example on iOS:
```javascript ```javascript
{ {
bitrate: 1000000 bitrate: 1000000
} }
``` ```
Example on Android:
```javascript
{
bitrate: 1000000
width: 1920
height: 1080
trackId: 'some-track-id'
}
```
Note: On Android, you must set the [reportBandwidth](#reportbandwidth) prop to enable this event. This is due to the high volume of events generated. Note: On Android, you must set the [reportBandwidth](#reportbandwidth) prop to enable this event. This is due to the high volume of events generated.
Platforms: Android Platforms: Android

View File

@ -7,8 +7,7 @@ protocol RCTPlayerObserverHandlerObjc {
func handleDidFailToFinishPlaying(notification:NSNotification!) func handleDidFailToFinishPlaying(notification:NSNotification!)
func handlePlaybackStalled(notification:NSNotification!) func handlePlaybackStalled(notification:NSNotification!)
func handlePlayerItemDidReachEnd(notification:NSNotification!) func handlePlayerItemDidReachEnd(notification:NSNotification!)
// unused func handleAVPlayerAccess(notification:NSNotification!)
// func handleAVPlayerAccess(notification:NSNotification!)
} }
protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc { protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc {
@ -25,7 +24,6 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc {
} }
class RCTPlayerObserver: NSObject { class RCTPlayerObserver: NSObject {
weak var _handlers: RCTPlayerObserverHandler? weak var _handlers: RCTPlayerObserverHandler?
var player:AVPlayer? { var player:AVPlayer? {
@ -108,7 +106,6 @@ class RCTPlayerObserver: NSObject {
func addPlayerItemObservers() { func addPlayerItemObservers() {
guard let playerItem = playerItem, let _handlers = _handlers else { return } guard let playerItem = playerItem, let _handlers = _handlers else { return }
_playerItemStatusObserver = playerItem.observe(\.status, options: [.new, .old], changeHandler: _handlers.handlePlayerItemStatusChange) _playerItemStatusObserver = playerItem.observe(\.status, options: [.new, .old], changeHandler: _handlers.handlePlayerItemStatusChange)
_playerPlaybackBufferEmptyObserver = playerItem.observe(\.isPlaybackBufferEmpty, options: [.new, .old], changeHandler: _handlers.handlePlaybackBufferKeyEmpty) _playerPlaybackBufferEmptyObserver = playerItem.observe(\.isPlaybackBufferEmpty, options: [.new, .old], changeHandler: _handlers.handlePlaybackBufferKeyEmpty)
_playerPlaybackLikelyToKeepUpObserver = playerItem.observe(\.isPlaybackLikelyToKeepUp, options: [.new, .old], changeHandler: _handlers.handlePlaybackLikelyToKeepUp) _playerPlaybackLikelyToKeepUpObserver = playerItem.observe(\.isPlaybackLikelyToKeepUp, options: [.new, .old], changeHandler: _handlers.handlePlaybackLikelyToKeepUp)
@ -121,7 +118,6 @@ class RCTPlayerObserver: NSObject {
_playerPlaybackLikelyToKeepUpObserver?.invalidate() _playerPlaybackLikelyToKeepUpObserver?.invalidate()
_playerTimedMetadataObserver?.invalidate() _playerTimedMetadataObserver?.invalidate()
} }
func addPlayerViewControllerObservers() { func addPlayerViewControllerObservers() {
guard let playerViewController = playerViewController, let _handlers = _handlers else { return } guard let playerViewController = playerViewController, let _handlers = _handlers else { return }
@ -182,10 +178,10 @@ class RCTPlayerObserver: NSObject {
func attachPlayerEventListeners() { func attachPlayerEventListeners() {
guard let _handlers = _handlers else {return} guard let _handlers = _handlers else {return}
NotificationCenter.default.removeObserver(_handlers, NotificationCenter.default.removeObserver(_handlers,
name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, name:NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object:player?.currentItem) object:player?.currentItem)
NotificationCenter.default.addObserver(_handlers, NotificationCenter.default.addObserver(_handlers,
selector:#selector(RCTPlayerObserverHandler.handlePlayerItemDidReachEnd(notification:)), selector:#selector(RCTPlayerObserverHandler.handlePlayerItemDidReachEnd(notification:)),
name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, name:NSNotification.Name.AVPlayerItemDidPlayToEndTime,
@ -194,17 +190,27 @@ class RCTPlayerObserver: NSObject {
NotificationCenter.default.removeObserver(_handlers, NotificationCenter.default.removeObserver(_handlers,
name:NSNotification.Name.AVPlayerItemPlaybackStalled, name:NSNotification.Name.AVPlayerItemPlaybackStalled,
object:nil) object:nil)
NotificationCenter.default.addObserver(_handlers, NotificationCenter.default.addObserver(_handlers,
selector:#selector(RCTPlayerObserverHandler.handlePlaybackStalled(notification:)), selector:#selector(RCTPlayerObserverHandler.handlePlaybackStalled(notification:)),
name:NSNotification.Name.AVPlayerItemPlaybackStalled, name:NSNotification.Name.AVPlayerItemPlaybackStalled,
object:nil) object:nil)
NotificationCenter.default.removeObserver(_handlers, NotificationCenter.default.removeObserver(_handlers,
name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime,
object:nil) object:nil)
NotificationCenter.default.addObserver(_handlers, NotificationCenter.default.addObserver(_handlers,
selector:#selector(RCTPlayerObserverHandler.handleDidFailToFinishPlaying(notification:)), selector:#selector(RCTPlayerObserverHandler.handleDidFailToFinishPlaying(notification:)),
name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime,
object:nil) object:nil)
NotificationCenter.default.removeObserver(_handlers, name: NSNotification.Name.AVPlayerItemNewAccessLogEntry, object: player?.currentItem)
NotificationCenter.default.addObserver(_handlers,
selector:#selector(RCTPlayerObserverHandlerObjc.handleAVPlayerAccess(notification:)),
name: NSNotification.Name.AVPlayerItemNewAccessLogEntry,
object: player?.currentItem)
} }
func clearPlayer() { func clearPlayer() {

View File

@ -94,7 +94,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc var onVideoBuffer: RCTDirectEventBlock? @objc var onVideoBuffer: RCTDirectEventBlock?
@objc var onVideoError: RCTDirectEventBlock? @objc var onVideoError: RCTDirectEventBlock?
@objc var onVideoProgress: RCTDirectEventBlock? @objc var onVideoProgress: RCTDirectEventBlock?
@objc var onBandwidthUpdate: RCTDirectEventBlock? @objc var onVideoBandwidthUpdate: RCTDirectEventBlock?
@objc var onVideoSeek: RCTDirectEventBlock? @objc var onVideoSeek: RCTDirectEventBlock?
@objc var onVideoEnd: RCTDirectEventBlock? @objc var onVideoEnd: RCTDirectEventBlock?
@objc var onTimedMetadata: RCTDirectEventBlock? @objc var onTimedMetadata: RCTDirectEventBlock?
@ -1336,15 +1336,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
} }
} }
//unused @objc func handleAVPlayerAccess(notification:NSNotification!) {
// @objc func handleAVPlayerAccess(notification:NSNotification!) { let accessLog:AVPlayerItemAccessLog! = (notification.object as! AVPlayerItem).accessLog()
// let accessLog:AVPlayerItemAccessLog! = (notification.object as! AVPlayerItem).accessLog() let lastEvent:AVPlayerItemAccessLogEvent! = accessLog.events.last
// let lastEvent:AVPlayerItemAccessLogEvent! = accessLog.events.last
// onVideoBandwidthUpdate?(["bitrate": lastEvent.observedBitrate, "target": reactTag])
// /* TODO: get this working }
// if (self.onBandwidthUpdate) {
// self.onBandwidthUpdate(@{@"bitrate": [NSNumber numberWithFloat:lastEvent.observedBitrate]});
// }
// */
// }
} }

View File

@ -44,7 +44,7 @@ RCT_EXPORT_VIEW_PROPERTY(onVideoLoad, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoBuffer, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoBuffer, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onBandwidthUpdate, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoBandwidthUpdate, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTDirectEventBlock);

View File

@ -150,9 +150,9 @@ export type OnProgressData = Readonly<{
export type OnBandwidthUpdateData = Readonly<{ export type OnBandwidthUpdateData = Readonly<{
bitrate: number; bitrate: number;
width: number; width?: number;
height: number; height?: number;
trackId: number; trackId?: number;
}>; }>;
export type OnSeekData = Readonly<{ export type OnSeekData = Readonly<{

View File

@ -131,12 +131,15 @@ export type OnAudioFocusChangedData = Readonly<{
export type OnBufferData = Readonly<{isBuffering: boolean}>; export type OnBufferData = Readonly<{isBuffering: boolean}>;
export type OnBandwidthUpdateData = Readonly<{ export type OnBandwidthUpdateData = Readonly<
bitrate: number; | {
width: number; bitrate: number;
height: number; width: number;
trackId: number; height: number;
}>; trackId: number;
}
| {bitrate: number}
>;
export interface ReactVideoEvents { export interface ReactVideoEvents {
onAudioBecomingNoisy?: () => void; //Android, iOS onAudioBecomingNoisy?: () => void; //Android, iOS