feat: add onVolumeChange event (#3322)

* feat: implement `onVolumeChange` event
This commit is contained in:
Krzysztof Moch 2023-11-04 18:11:54 +01:00 committed by GitHub
parent 50e0b33bf6
commit cdbc856387
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 1 deletions

View File

@ -1,6 +1,7 @@
## Changelog
## Next
- Android, iOS: add onVolumeChange event #3322
### Version 6.0.0-alpha.9
- All: add built-in typescript support [#3266](https://github.com/react-native-video/react-native-video/pull/3266)

View File

@ -50,6 +50,7 @@ public class VideoEventEmitter {
private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy";
private static final String EVENT_AUDIO_FOCUS_CHANGE = "onAudioFocusChanged";
private static final String EVENT_PLAYBACK_RATE_CHANGE = "onPlaybackRateChange";
private static final String EVENT_VOLUME_CHANGE = "onVolumeChange";
private static final String EVENT_AUDIO_TRACKS = "onAudioTracks";
private static final String EVENT_TEXT_TRACKS = "onTextTracks";
private static final String EVENT_VIDEO_TRACKS = "onVideoTracks";
@ -76,6 +77,7 @@ public class VideoEventEmitter {
EVENT_AUDIO_BECOMING_NOISY,
EVENT_AUDIO_FOCUS_CHANGE,
EVENT_PLAYBACK_RATE_CHANGE,
EVENT_VOLUME_CHANGE,
EVENT_AUDIO_TRACKS,
EVENT_TEXT_TRACKS,
EVENT_VIDEO_TRACKS,
@ -105,6 +107,7 @@ public class VideoEventEmitter {
EVENT_AUDIO_BECOMING_NOISY,
EVENT_AUDIO_FOCUS_CHANGE,
EVENT_PLAYBACK_RATE_CHANGE,
EVENT_VOLUME_CHANGE,
EVENT_AUDIO_TRACKS,
EVENT_TEXT_TRACKS,
EVENT_VIDEO_TRACKS,
@ -140,6 +143,7 @@ public class VideoEventEmitter {
private static final String EVENT_PROP_HAS_AUDIO_FOCUS = "hasAudioFocus";
private static final String EVENT_PROP_IS_BUFFERING = "isBuffering";
private static final String EVENT_PROP_PLAYBACK_RATE = "playbackRate";
private static final String EVENT_PROP_VOLUME = "volume";
private static final String EVENT_PROP_ERROR = "error";
private static final String EVENT_PROP_ERROR_STRING = "errorString";
@ -379,6 +383,11 @@ public class VideoEventEmitter {
receiveEvent(EVENT_PLAYBACK_RATE_CHANGE, map);
}
public void volumeChange(float volume) {
WritableMap map = Arguments.createMap();
map.putDouble(EVENT_PROP_VOLUME, volume);
receiveEvent(EVENT_VOLUME_CHANGE, map);
}
public void timedMetadata(ArrayList<TimedMetadata> _metadataArrayList) {
if (_metadataArrayList.size() == 0) {

View File

@ -1434,6 +1434,11 @@ public class ReactExoplayerView extends FrameLayout implements
eventEmitter.playbackRateChange(params.speed);
}
@Override
public void onVolumeChanged(float volume) {
eventEmitter.volumeChange(volume);
}
@Override
public void onIsPlayingChanged(boolean isPlaying) {
eventEmitter.playbackStateChanged(isPlaying);

View File

@ -29,6 +29,7 @@ This page shows the list of available callbacks to handle player notifications
| [onTimedMetadata](#ontimedmetadata) | Android, iOS |
| [onTextTracks](#ontexttracks) | Android |
| [onVideoTracks](#onvideotracks) | Android |
| [onVolumeChange](#onvolumechange) | Android, iOS |
## Details
@ -507,4 +508,23 @@ Example:
}
```
Platforms: Android
Platforms: Android
### `onVolumeChange`
Callback function that is called when the volume of player changes.
> Note: This event applies to the volume of the player, not the volume of the device.
Payload:
Property | Type | Description
--- | --- | ---
volume | number | The volume of the player (between 0 and 1)
Example:
```javascript
{
volume: 0.5
}
```
Platforms: Android, iOS

View File

@ -19,6 +19,7 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc {
func handlePlaybackBufferKeyEmpty(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
func handlePlaybackLikelyToKeepUp(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>)
func handleVolumeChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>)
func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange<Bool>)
func handleViewControllerOverlayViewFrameChange(overlayView:UIView, change:NSKeyValueObservedChange<CGRect>)
}
@ -74,6 +75,7 @@ class RCTPlayerObserver: NSObject {
private var _timeObserver:Any?
private var _playerRateChangeObserver:NSKeyValueObservation?
private var _playerVolumeChangeObserver:NSKeyValueObservation?
private var _playerExternalPlaybackActiveObserver:NSKeyValueObservation?
private var _playerItemStatusObserver:NSKeyValueObservation?
private var _playerPlaybackBufferEmptyObserver:NSKeyValueObservation?
@ -95,6 +97,7 @@ class RCTPlayerObserver: NSObject {
}
_playerRateChangeObserver = player.observe(\.rate, options: [.old], changeHandler: _handlers.handlePlaybackRateChange)
_playerVolumeChangeObserver = player.observe(\.volume, options: [.old] ,changeHandler: _handlers.handleVolumeChange)
_playerExternalPlaybackActiveObserver = player.observe(\.isExternalPlaybackActive, changeHandler: _handlers.handleExternalPlaybackActiveChange)
}

View File

@ -107,6 +107,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc var onPlaybackStalled: RCTDirectEventBlock?
@objc var onPlaybackResume: RCTDirectEventBlock?
@objc var onPlaybackRateChange: RCTDirectEventBlock?
@objc var onVolumeChange: RCTDirectEventBlock?
@objc var onVideoPlaybackStateChanged: RCTDirectEventBlock?
@objc var onVideoExternalPlaybackChange: RCTDirectEventBlock?
@objc var onPictureInPictureStatusChanged: RCTDirectEventBlock?
@ -1237,6 +1238,17 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
_playbackStalled = false
}
}
func handleVolumeChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) {
guard let _player = _player else { return }
if(player.rate == change.oldValue && change.oldValue != nil) {
return
}
onVolumeChange?(["volume": NSNumber(value: _player.volume),
"target": reactTag as Any])
}
func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange<Bool>) {
guard let _player = _player else { return }

View File

@ -57,6 +57,7 @@ RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVolumeChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoPlaybackStateChanged, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onGetLicense, RCTDirectEventBlock);

View File

@ -82,6 +82,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onFullscreenPlayerDidDismiss,
onReadyForDisplay,
onPlaybackRateChange,
onVolumeChange,
onAudioBecomingNoisy,
onPictureInPictureStatusChanged,
onRestoreUserInterfaceForPictureInPictureStop,
@ -344,6 +345,13 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
[onPlaybackRateChange],
);
const _onVolumeChange = useCallback(
(e: NativeSyntheticEvent<Readonly<{volume: number}>>) => {
onVolumeChange?.(e.nativeEvent);
},
[onVolumeChange],
);
const _onReadyForDisplay = useCallback(() => {
setShowPoster(false);
onReadyForDisplay?.();
@ -509,6 +517,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onAudioFocusChanged={_onAudioFocusChanged}
onReadyForDisplay={_onReadyForDisplay}
onPlaybackRateChange={_onPlaybackRateChange}
onVolumeChange={_onVolumeChange}
onVideoAudioBecomingNoisy={onAudioBecomingNoisy}
onPictureInPictureStatusChanged={_onPictureInPictureStatusChanged}
onRestoreUserInterfaceForPictureInPictureStop={

View File

@ -218,6 +218,10 @@ export type OnPlaybackData = Readonly<{
playbackRate: number;
}>;
export type onVolumeChangeData = Readonly<{
volume: number;
}>;
export type OnExternalPlaybackChangeData = Readonly<{
isExternalPlaybackActive: boolean;
}>;
@ -326,6 +330,7 @@ export interface VideoNativeProps extends ViewProps {
) => void; // ios, android
onReadyForDisplay?: (event: NativeSyntheticEvent<Readonly<object>>) => void;
onPlaybackRateChange?: (event: NativeSyntheticEvent<OnPlaybackData>) => void; // all
onVolumeChange?: (event: NativeSyntheticEvent<onVolumeChangeData>) => void; // android, ios
onVideoExternalPlaybackChange?: (
event: NativeSyntheticEvent<OnExternalPlaybackChangeData>,
) => void;

View File

@ -95,6 +95,10 @@ export type OnPlaybackData = Readonly<{
playbackRate: number;
}>;
export type OnVolumeChangeData = Readonly<{
volume: number;
}>;
export type OnExternalPlaybackChangeData = Readonly<{
isExternalPlaybackActive: boolean;
}>;
@ -153,6 +157,7 @@ export interface ReactVideoEvents {
e: OnPictureInPictureStatusChangedData,
) => void; //iOS
onPlaybackRateChange?: (e: OnPlaybackData) => void; //All
onVolumeChange?: (e: OnVolumeChangeData) => void; //Android, iOS
onProgress?: (e: OnProgressData) => void; //All
onReadyForDisplay?: () => void; //Android, iOS
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS