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

refactor: migrate ref methods to command #3953

Closed
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.media3.common.util.Util;

import com.brentvatne.common.api.BufferConfig;
import com.brentvatne.common.api.BufferingStrategy;
Expand All @@ -22,16 +21,15 @@
import com.brentvatne.common.toolbox.DebugLog;
import com.brentvatne.common.toolbox.ReactBridgeUtils;
import com.brentvatne.react.ReactNativeVideoManager;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;

import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Nullable;

Expand All @@ -42,7 +40,6 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_SRC = "src";
private static final String PROP_AD_TAG_URL = "adTagUrl";
private static final String PROP_DRM = "drm";
private static final String PROP_SRC_HEADERS = "requestHeaders";
private static final String PROP_RESIZE_MODE = "resizeMode";
private static final String PROP_REPEAT = "repeat";
private static final String PROP_SELECTED_AUDIO_TRACK = "selectedAudioTrack";
Expand Down Expand Up @@ -82,6 +79,10 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_DEBUG = "debug";
private static final String PROP_CONTROLS_STYLES = "controlsStyles";

private static final String CMD_SET_PLAYER_PAUSE_STATE = "setPlayerPauseState";
private static final String CMD_SEEK = "seek";
private static final String CMD_SET_VOLUME = "setVolume";
private static final String CMD_SET_FULLSCREEN = "setFullscreen";
KrzysztofMoch marked this conversation as resolved.
Show resolved Hide resolved

private final ReactExoplayerConfig config;

Expand Down Expand Up @@ -355,4 +356,41 @@ public void setControlsStyles(final ReactExoplayerView videoView, @Nullable Read
ControlsConfig controlsConfig = ControlsConfig.parse(controlsStyles);
videoView.setControlsStyles(controlsConfig);
}
}

@Override
public void receiveCommand(@NonNull ReactExoplayerView videoView, String commandId, @Nullable ReadableArray args) {
switch (commandId) {
case CMD_SET_PLAYER_PAUSE_STATE:
if (args == null || args.size() < 1) {
throw new JSApplicationIllegalArgumentException("Illegal number of arguments for '" + CMD_SET_PLAYER_PAUSE_STATE + "' command");
}
Boolean paused = args.getBoolean(0);
videoView.setPausedModifier(paused);
break;
case CMD_SEEK:
if (args == null || args.size() < 1) {
throw new JSApplicationIllegalArgumentException("Illegal number of arguments for '" + CMD_SEEK + "' command");
}
Double time = args.getDouble(0);
videoView.seekTo((Long)Math.round(time * 1000f));
break;
case CMD_SET_VOLUME:
if (args == null || args.size() < 1) {
throw new JSApplicationIllegalArgumentException("Illegal number of arguments for '" + CMD_SET_VOLUME + "' command");
}
Float volume = (float) args.getDouble(0);
videoView.setVolumeModifier(volume);
break;
case CMD_SET_FULLSCREEN:
if (args == null || args.size() < 1) {
throw new JSApplicationIllegalArgumentException("Illegal number of arguments for '" + CMD_SET_FULLSCREEN + "' command");
}
boolean fullscreen = args.getBoolean(0);
videoView.setFullscreen(fullscreen);
break;
default:
break;
}
super.receiveCommand(videoView, commandId, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ class VideoDecoderPropertiesModule(reactContext: ReactApplicationContext?) : Rea
companion object {
private val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
private const val SECURITY_LEVEL_PROPERTY = "securityLevel"
private const val REACT_CLASS = "VideoDecoderProperties"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it really necessary to change the module name ?

Copy link
Collaborator Author

@YangJonghun YangJonghun Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's not required, but I changed it to reduce the chance of duplicates with other library(or core).

private const val REACT_CLASS = "RNVDecoderPropertiesModule"
}
}
36 changes: 0 additions & 36 deletions android/src/main/java/com/brentvatne/react/VideoManagerModule.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.brentvatne.react

import com.brentvatne.common.toolbox.ReactBridgeUtils
import com.brentvatne.exoplayer.ReactExoplayerView
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.common.UIManagerType
import kotlin.math.roundToInt

class VideoManagerModule(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {
override fun getName(): String = REACT_CLASS
Expand All @@ -36,46 +33,13 @@ class VideoManagerModule(reactContext: ReactApplicationContext?) : ReactContextB
}
}

@ReactMethod
fun setPlayerPauseState(paused: Boolean?, reactTag: Int) {
performOnPlayerView(reactTag) {
it?.setPausedModifier(paused!!)
}
}

@ReactMethod
fun seek(info: ReadableMap, reactTag: Int) {
if (!info.hasKey("time")) {
return
}

val time = ReactBridgeUtils.safeGetInt(info, "time")
performOnPlayerView(reactTag) {
it?.seekTo((time * 1000f).roundToInt().toLong())
}
}

@ReactMethod
fun setVolume(volume: Float, reactTag: Int) {
performOnPlayerView(reactTag) {
it?.setVolumeModifier(volume)
}
}

@ReactMethod
fun getCurrentPosition(reactTag: Int, promise: Promise) {
performOnPlayerView(reactTag) {
it?.getCurrentPosition(promise)
}
}

@ReactMethod
fun setFullScreen(fullScreen: Boolean, reactTag: Int) {
performOnPlayerView(reactTag) {
it?.setFullscreen(fullScreen)
}
}

companion object {
private const val REACT_CLASS = "VideoManager"
}
Expand Down
4 changes: 4 additions & 0 deletions ios/RCTVideo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
0177D39827170A7A00F5BE18 /* RCTVideo-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTVideo-Bridging-Header.h"; path = "Video/RCTVideo-Bridging-Header.h"; sourceTree = "<group>"; };
0177D39927170A7A00F5BE18 /* RCTVideo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RCTVideo.swift; path = Video/RCTVideo.swift; sourceTree = "<group>"; };
134814201AA4EA6300B7C361 /* libRCTVideo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTVideo.a; sourceTree = BUILT_PRODUCTS_DIR; };
61E605932C30612C0080E2CD /* RCTDecoderPropertiesModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RCTDecoderPropertiesModule.h; path = Video/RCTDecoderPropertiesModule.h; sourceTree = "<group>"; };
61E605942C30616C0080E2CD /* RCTDecoderPropertiesModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RCTDecoderPropertiesModule.m; path = Video/RCTDecoderPropertiesModule.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -93,6 +95,8 @@
0177D39927170A7A00F5BE18 /* RCTVideo.swift */,
0177D39727170A7A00F5BE18 /* RCTVideoManager.m */,
0177D39227170A7A00F5BE18 /* RCTVideoManager.swift */,
61E605932C30612C0080E2CD /* RCTDecoderPropertiesModule.h */,
61E605942C30616C0080E2CD /* RCTDecoderPropertiesModule.m */,
0177D39427170A7A00F5BE18 /* RCTVideoPlayerViewController.swift */,
0177D39627170A7A00F5BE18 /* RCTVideoPlayerViewControllerDelegate.swift */,
0177D39327170A7A00F5BE18 /* UIView+FindUIViewController.swift */,
Expand Down
3 changes: 3 additions & 0 deletions ios/Video/RCTDecoderPropertiesModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#import <React/RCTBridgeModule.h>
@interface RCTDecoderPropertiesModule : NSObject <RCTBridgeModule>
@end
13 changes: 13 additions & 0 deletions ios/Video/RCTDecoderPropertiesModule.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import "RCTDecoderPropertiesModule.h"

@implementation RCTDecoderPropertiesModule

RCT_EXPORT_MODULE(RNVDecoderPropertiesModule);

RCT_EXPORT_METHOD(getWidevineLevel : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {}
Copy link
Collaborator

@freeboub freeboub Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should al least resolve or reject the Promise... (maybe reject with an error "not implemented") , for these 3 methods

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions are meaningless but, acceptable.
I think we should throw an error to notify library contributors.
(we should wrapping decoder properties module on JS side)


RCT_EXPORT_METHOD(isCodecSupported : (NSString*)mimeType width : (NSInteger*)width height : (NSInteger*)height) {}

RCT_EXPORT_METHOD(isHEVCSupported : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {}

@end
32 changes: 8 additions & 24 deletions ios/Video/RCTVideo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -754,29 +754,27 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
}

@objc
func setSeek(_ info: NSDictionary!) {
let seekTime: NSNumber! = info["time"] as! NSNumber
let seekTolerance: NSNumber! = info["tolerance"] as! NSNumber
func setSeek(_ time: NSNumber, _ tolerance: NSNumber) {
let item: AVPlayerItem? = _player?.currentItem
guard item != nil, let player = _player, let item, item.status == AVPlayerItem.Status.readyToPlay else {
_pendingSeek = true
_pendingSeekTime = seekTime.floatValue
_pendingSeekTime = time.floatValue
return
}

RCTPlayerOperations.seek(
player: player,
playerItem: item,
paused: _paused,
seekTime: seekTime.floatValue,
seekTolerance: seekTolerance.floatValue
seekTime: time.floatValue,
seekTolerance: tolerance.floatValue
) { [weak self] (_: Bool) in
guard let self else { return }

self._playerObserver.addTimeObserverIfNotSet()
self.setPaused(self._paused)
self.onVideoSeek?(["currentTime": NSNumber(value: Float(CMTimeGetSeconds(item.currentTime()))),
"seekTime": seekTime,
"seekTime": time,
"target": self.reactTag])
}

Expand Down Expand Up @@ -1293,7 +1291,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
// MARK: - Export

@objc
func save(options: NSDictionary!, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
func save(_ options: NSDictionary!, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
RCTVideoSave.save(
options: options,
resolve: resolve,
Expand All @@ -1310,14 +1308,6 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
_resouceLoaderDelegate?.setLicenseResultError(error, licenseUrl)
}

func dismissFullscreenPlayer() {
setFullscreen(false)
}

func presentFullscreenPlayer() {
setFullscreen(true)
}

// MARK: - RCTPlayerObserverHandler

func handleTimeUpdate(time _: CMTime) {
Expand Down Expand Up @@ -1371,18 +1361,12 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

Task {
if self._pendingSeek {
self.setSeek([
"time": NSNumber(value: self._pendingSeekTime),
"tolerance": NSNumber(value: 100),
])
self.setSeek(NSNumber(value: self._pendingSeekTime), NSNumber(value: 100))
self._pendingSeek = false
}

if self._startPosition >= 0 {
self.setSeek([
"time": NSNumber(value: self._startPosition),
"tolerance": NSNumber(value: 100),
])
self.setSeek(NSNumber(value: self._startPosition), NSNumber(value: 100))
self._startPosition = -1
}

Expand Down
36 changes: 13 additions & 23 deletions ios/Video/RCTVideoManager.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "React/RCTViewManager.h"
#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE (RCTVideoManager, RCTViewManager)

Expand Down Expand Up @@ -68,31 +68,21 @@ @interface RCT_EXTERN_MODULE (RCTVideoManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(onAudioTracks, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onTextTrackDataChanged, RCTDirectEventBlock);

RCT_EXTERN_METHOD(seek : (nonnull NSNumber*)reactTag time : (nonnull NSNumber*)time tolerance : (nonnull NSNumber*)tolerance)
RCT_EXTERN_METHOD(setLicenseResult : (nonnull NSNumber*)reactTag lisence : (NSString*)license licenseUrl : (NSString*)licenseUrl)
RCT_EXTERN_METHOD(setLicenseResultError : (nonnull NSNumber*)reactTag error : (NSString*)error licenseUrl : (NSString*)licenseUrl)
RCT_EXTERN_METHOD(setPlayerPauseState : (nonnull NSNumber*)reactTag paused : (nonnull BOOL)paused)
RCT_EXTERN_METHOD(setVolume : (nonnull NSNumber*)reactTag volume : (nonnull float*)volume)
RCT_EXTERN_METHOD(setFullScreen : (nonnull NSNumber*)reactTag fullscreen : (nonnull BOOL)fullScreen)

RCT_EXTERN_METHOD(save
: (NSDictionary*)options reactTag
: (nonnull NSNumber*)reactTag resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (nonnull NSNumber*)reactTag options
: (NSDictionary*)options resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(seek : (NSDictionary*)info reactTag : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(setLicenseResult : (NSString*)license licenseUrl : (NSString*)licenseUrl reactTag : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(setLicenseResultError : (NSString*)error licenseUrl : (NSString*)licenseUrl reactTag : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(setPlayerPauseState : (nonnull NSNumber*)paused reactTag : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(presentFullscreenPlayer : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(dismissFullscreenPlayer : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(setVolume : (nonnull float*)volume reactTag : (nonnull NSNumber*)reactTag)

RCT_EXTERN_METHOD(getCurrentPosition
: (nonnull NSNumber*)reactTag resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (nonnull NSNumber*)reactTag resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(setFullScreen : (BOOL)fullScreen reactTag : (nonnull NSNumber*)reactTag)

@end
Loading
Loading