feat: add onVolumeChange
event (#3322)
* feat: implement `onVolumeChange` event
This commit is contained in:
parent
50e0b33bf6
commit
cdbc856387
@ -1,6 +1,7 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
- Android, iOS: add onVolumeChange event #3322
|
||||||
|
|
||||||
### Version 6.0.0-alpha.9
|
### Version 6.0.0-alpha.9
|
||||||
- All: add built-in typescript support [#3266](https://github.com/react-native-video/react-native-video/pull/3266)
|
- All: add built-in typescript support [#3266](https://github.com/react-native-video/react-native-video/pull/3266)
|
||||||
|
@ -50,6 +50,7 @@ public class VideoEventEmitter {
|
|||||||
private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy";
|
private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy";
|
||||||
private static final String EVENT_AUDIO_FOCUS_CHANGE = "onAudioFocusChanged";
|
private static final String EVENT_AUDIO_FOCUS_CHANGE = "onAudioFocusChanged";
|
||||||
private static final String EVENT_PLAYBACK_RATE_CHANGE = "onPlaybackRateChange";
|
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_AUDIO_TRACKS = "onAudioTracks";
|
||||||
private static final String EVENT_TEXT_TRACKS = "onTextTracks";
|
private static final String EVENT_TEXT_TRACKS = "onTextTracks";
|
||||||
private static final String EVENT_VIDEO_TRACKS = "onVideoTracks";
|
private static final String EVENT_VIDEO_TRACKS = "onVideoTracks";
|
||||||
@ -76,6 +77,7 @@ public class VideoEventEmitter {
|
|||||||
EVENT_AUDIO_BECOMING_NOISY,
|
EVENT_AUDIO_BECOMING_NOISY,
|
||||||
EVENT_AUDIO_FOCUS_CHANGE,
|
EVENT_AUDIO_FOCUS_CHANGE,
|
||||||
EVENT_PLAYBACK_RATE_CHANGE,
|
EVENT_PLAYBACK_RATE_CHANGE,
|
||||||
|
EVENT_VOLUME_CHANGE,
|
||||||
EVENT_AUDIO_TRACKS,
|
EVENT_AUDIO_TRACKS,
|
||||||
EVENT_TEXT_TRACKS,
|
EVENT_TEXT_TRACKS,
|
||||||
EVENT_VIDEO_TRACKS,
|
EVENT_VIDEO_TRACKS,
|
||||||
@ -105,6 +107,7 @@ public class VideoEventEmitter {
|
|||||||
EVENT_AUDIO_BECOMING_NOISY,
|
EVENT_AUDIO_BECOMING_NOISY,
|
||||||
EVENT_AUDIO_FOCUS_CHANGE,
|
EVENT_AUDIO_FOCUS_CHANGE,
|
||||||
EVENT_PLAYBACK_RATE_CHANGE,
|
EVENT_PLAYBACK_RATE_CHANGE,
|
||||||
|
EVENT_VOLUME_CHANGE,
|
||||||
EVENT_AUDIO_TRACKS,
|
EVENT_AUDIO_TRACKS,
|
||||||
EVENT_TEXT_TRACKS,
|
EVENT_TEXT_TRACKS,
|
||||||
EVENT_VIDEO_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_HAS_AUDIO_FOCUS = "hasAudioFocus";
|
||||||
private static final String EVENT_PROP_IS_BUFFERING = "isBuffering";
|
private static final String EVENT_PROP_IS_BUFFERING = "isBuffering";
|
||||||
private static final String EVENT_PROP_PLAYBACK_RATE = "playbackRate";
|
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 = "error";
|
||||||
private static final String EVENT_PROP_ERROR_STRING = "errorString";
|
private static final String EVENT_PROP_ERROR_STRING = "errorString";
|
||||||
@ -379,6 +383,11 @@ public class VideoEventEmitter {
|
|||||||
receiveEvent(EVENT_PLAYBACK_RATE_CHANGE, map);
|
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) {
|
public void timedMetadata(ArrayList<TimedMetadata> _metadataArrayList) {
|
||||||
if (_metadataArrayList.size() == 0) {
|
if (_metadataArrayList.size() == 0) {
|
||||||
|
@ -1434,6 +1434,11 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
eventEmitter.playbackRateChange(params.speed);
|
eventEmitter.playbackRateChange(params.speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVolumeChanged(float volume) {
|
||||||
|
eventEmitter.volumeChange(volume);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIsPlayingChanged(boolean isPlaying) {
|
public void onIsPlayingChanged(boolean isPlaying) {
|
||||||
eventEmitter.playbackStateChanged(isPlaying);
|
eventEmitter.playbackStateChanged(isPlaying);
|
||||||
|
@ -29,6 +29,7 @@ This page shows the list of available callbacks to handle player notifications
|
|||||||
| [onTimedMetadata](#ontimedmetadata) | Android, iOS |
|
| [onTimedMetadata](#ontimedmetadata) | Android, iOS |
|
||||||
| [onTextTracks](#ontexttracks) | Android |
|
| [onTextTracks](#ontexttracks) | Android |
|
||||||
| [onVideoTracks](#onvideotracks) | Android |
|
| [onVideoTracks](#onvideotracks) | Android |
|
||||||
|
| [onVolumeChange](#onvolumechange) | Android, iOS |
|
||||||
|
|
||||||
|
|
||||||
## Details
|
## 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
|
@ -19,6 +19,7 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc {
|
|||||||
func handlePlaybackBufferKeyEmpty(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
|
func handlePlaybackBufferKeyEmpty(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
|
||||||
func handlePlaybackLikelyToKeepUp(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
|
func handlePlaybackLikelyToKeepUp(playerItem:AVPlayerItem, change:NSKeyValueObservedChange<Bool>)
|
||||||
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>)
|
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>)
|
||||||
|
func handleVolumeChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>)
|
||||||
func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange<Bool>)
|
func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange<Bool>)
|
||||||
func handleViewControllerOverlayViewFrameChange(overlayView:UIView, change:NSKeyValueObservedChange<CGRect>)
|
func handleViewControllerOverlayViewFrameChange(overlayView:UIView, change:NSKeyValueObservedChange<CGRect>)
|
||||||
}
|
}
|
||||||
@ -74,6 +75,7 @@ class RCTPlayerObserver: NSObject {
|
|||||||
private var _timeObserver:Any?
|
private var _timeObserver:Any?
|
||||||
|
|
||||||
private var _playerRateChangeObserver:NSKeyValueObservation?
|
private var _playerRateChangeObserver:NSKeyValueObservation?
|
||||||
|
private var _playerVolumeChangeObserver:NSKeyValueObservation?
|
||||||
private var _playerExternalPlaybackActiveObserver:NSKeyValueObservation?
|
private var _playerExternalPlaybackActiveObserver:NSKeyValueObservation?
|
||||||
private var _playerItemStatusObserver:NSKeyValueObservation?
|
private var _playerItemStatusObserver:NSKeyValueObservation?
|
||||||
private var _playerPlaybackBufferEmptyObserver:NSKeyValueObservation?
|
private var _playerPlaybackBufferEmptyObserver:NSKeyValueObservation?
|
||||||
@ -95,6 +97,7 @@ class RCTPlayerObserver: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_playerRateChangeObserver = player.observe(\.rate, options: [.old], changeHandler: _handlers.handlePlaybackRateChange)
|
_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)
|
_playerExternalPlaybackActiveObserver = player.observe(\.isExternalPlaybackActive, changeHandler: _handlers.handleExternalPlaybackActiveChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
@objc var onPlaybackStalled: RCTDirectEventBlock?
|
@objc var onPlaybackStalled: RCTDirectEventBlock?
|
||||||
@objc var onPlaybackResume: RCTDirectEventBlock?
|
@objc var onPlaybackResume: RCTDirectEventBlock?
|
||||||
@objc var onPlaybackRateChange: RCTDirectEventBlock?
|
@objc var onPlaybackRateChange: RCTDirectEventBlock?
|
||||||
|
@objc var onVolumeChange: RCTDirectEventBlock?
|
||||||
@objc var onVideoPlaybackStateChanged: RCTDirectEventBlock?
|
@objc var onVideoPlaybackStateChanged: RCTDirectEventBlock?
|
||||||
@objc var onVideoExternalPlaybackChange: RCTDirectEventBlock?
|
@objc var onVideoExternalPlaybackChange: RCTDirectEventBlock?
|
||||||
@objc var onPictureInPictureStatusChanged: RCTDirectEventBlock?
|
@objc var onPictureInPictureStatusChanged: RCTDirectEventBlock?
|
||||||
@ -1237,6 +1238,17 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
_playbackStalled = false
|
_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>) {
|
func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange<Bool>) {
|
||||||
guard let _player = _player else { return }
|
guard let _player = _player else { return }
|
||||||
|
@ -57,6 +57,7 @@ RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTDirectEventBlock);
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(onVolumeChange, RCTDirectEventBlock);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onVideoPlaybackStateChanged, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onVideoPlaybackStateChanged, RCTDirectEventBlock);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(onGetLicense, RCTDirectEventBlock);
|
RCT_EXPORT_VIEW_PROPERTY(onGetLicense, RCTDirectEventBlock);
|
||||||
|
@ -82,6 +82,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
onFullscreenPlayerDidDismiss,
|
onFullscreenPlayerDidDismiss,
|
||||||
onReadyForDisplay,
|
onReadyForDisplay,
|
||||||
onPlaybackRateChange,
|
onPlaybackRateChange,
|
||||||
|
onVolumeChange,
|
||||||
onAudioBecomingNoisy,
|
onAudioBecomingNoisy,
|
||||||
onPictureInPictureStatusChanged,
|
onPictureInPictureStatusChanged,
|
||||||
onRestoreUserInterfaceForPictureInPictureStop,
|
onRestoreUserInterfaceForPictureInPictureStop,
|
||||||
@ -344,6 +345,13 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
[onPlaybackRateChange],
|
[onPlaybackRateChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const _onVolumeChange = useCallback(
|
||||||
|
(e: NativeSyntheticEvent<Readonly<{volume: number}>>) => {
|
||||||
|
onVolumeChange?.(e.nativeEvent);
|
||||||
|
},
|
||||||
|
[onVolumeChange],
|
||||||
|
);
|
||||||
|
|
||||||
const _onReadyForDisplay = useCallback(() => {
|
const _onReadyForDisplay = useCallback(() => {
|
||||||
setShowPoster(false);
|
setShowPoster(false);
|
||||||
onReadyForDisplay?.();
|
onReadyForDisplay?.();
|
||||||
@ -509,6 +517,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
onAudioFocusChanged={_onAudioFocusChanged}
|
onAudioFocusChanged={_onAudioFocusChanged}
|
||||||
onReadyForDisplay={_onReadyForDisplay}
|
onReadyForDisplay={_onReadyForDisplay}
|
||||||
onPlaybackRateChange={_onPlaybackRateChange}
|
onPlaybackRateChange={_onPlaybackRateChange}
|
||||||
|
onVolumeChange={_onVolumeChange}
|
||||||
onVideoAudioBecomingNoisy={onAudioBecomingNoisy}
|
onVideoAudioBecomingNoisy={onAudioBecomingNoisy}
|
||||||
onPictureInPictureStatusChanged={_onPictureInPictureStatusChanged}
|
onPictureInPictureStatusChanged={_onPictureInPictureStatusChanged}
|
||||||
onRestoreUserInterfaceForPictureInPictureStop={
|
onRestoreUserInterfaceForPictureInPictureStop={
|
||||||
|
@ -218,6 +218,10 @@ export type OnPlaybackData = Readonly<{
|
|||||||
playbackRate: number;
|
playbackRate: number;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
export type onVolumeChangeData = Readonly<{
|
||||||
|
volume: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
export type OnExternalPlaybackChangeData = Readonly<{
|
export type OnExternalPlaybackChangeData = Readonly<{
|
||||||
isExternalPlaybackActive: boolean;
|
isExternalPlaybackActive: boolean;
|
||||||
}>;
|
}>;
|
||||||
@ -326,6 +330,7 @@ export interface VideoNativeProps extends ViewProps {
|
|||||||
) => void; // ios, android
|
) => void; // ios, android
|
||||||
onReadyForDisplay?: (event: NativeSyntheticEvent<Readonly<object>>) => void;
|
onReadyForDisplay?: (event: NativeSyntheticEvent<Readonly<object>>) => void;
|
||||||
onPlaybackRateChange?: (event: NativeSyntheticEvent<OnPlaybackData>) => void; // all
|
onPlaybackRateChange?: (event: NativeSyntheticEvent<OnPlaybackData>) => void; // all
|
||||||
|
onVolumeChange?: (event: NativeSyntheticEvent<onVolumeChangeData>) => void; // android, ios
|
||||||
onVideoExternalPlaybackChange?: (
|
onVideoExternalPlaybackChange?: (
|
||||||
event: NativeSyntheticEvent<OnExternalPlaybackChangeData>,
|
event: NativeSyntheticEvent<OnExternalPlaybackChangeData>,
|
||||||
) => void;
|
) => void;
|
||||||
|
@ -95,6 +95,10 @@ export type OnPlaybackData = Readonly<{
|
|||||||
playbackRate: number;
|
playbackRate: number;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
export type OnVolumeChangeData = Readonly<{
|
||||||
|
volume: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
export type OnExternalPlaybackChangeData = Readonly<{
|
export type OnExternalPlaybackChangeData = Readonly<{
|
||||||
isExternalPlaybackActive: boolean;
|
isExternalPlaybackActive: boolean;
|
||||||
}>;
|
}>;
|
||||||
@ -153,6 +157,7 @@ export interface ReactVideoEvents {
|
|||||||
e: OnPictureInPictureStatusChangedData,
|
e: OnPictureInPictureStatusChangedData,
|
||||||
) => void; //iOS
|
) => void; //iOS
|
||||||
onPlaybackRateChange?: (e: OnPlaybackData) => void; //All
|
onPlaybackRateChange?: (e: OnPlaybackData) => void; //All
|
||||||
|
onVolumeChange?: (e: OnVolumeChangeData) => void; //Android, iOS
|
||||||
onProgress?: (e: OnProgressData) => void; //All
|
onProgress?: (e: OnProgressData) => void; //All
|
||||||
onReadyForDisplay?: () => void; //Android, iOS
|
onReadyForDisplay?: () => void; //Android, iOS
|
||||||
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS
|
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS
|
||||||
|
Loading…
Reference in New Issue
Block a user