Reputation: 1
I have written a native module in Java for playing Videos. As per the logs, I can see that the video url and the focus was set successfully. However, the logs in the VideoView
listeners like setOnPreparedListener
never gets triggered (the logs never get printed
) and so the video never starts playing.
Note: This code works fine in a Native Android Project.
I am not sure if I am missing something here.
import static java.security.AccessController.getContext;
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.MediaController;
import android.widget.VideoView;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
public class ReactVideoViewManager extends SimpleViewManager<VideoView> {
public static final String REACT_CLASS = "ReactVideoView";
private static final String TAG = "RNViewManager";
ReactApplicationContext reactContext;
@NonNull
@Override
public String getName() {
return REACT_CLASS;
}
@NonNull
@Override
protected VideoView createViewInstance(@NonNull ThemedReactContext reactContext) {
VideoView videoView = new VideoView(reactContext);
MediaController mediaController = new MediaController(reactContext);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
Log.d(TAG, "VideoView Id when creating: " + videoView.getId());
return videoView;
}
@ReactProp(name = "source")
public void setVideoSource(VideoView videoView, @NonNull String videoUrl) {
// Setup listeners
videoView.setOnPreparedListener(mp -> {
Log.d(TAG, "Video is ready");
mp.start(); // Start playback when ready
});
videoView.setOnErrorListener((mp, what, extra) -> {
Log.e(TAG, "Error occurred: what=" + what + " extra=" + extra);
return true; // Return true to consume the error
});
videoView.setOnCompletionListener(mp -> {
Log.d(TAG, "Playback completed");
});
Log.d(TAG, "VideoView Id when adding URI: " + videoView.getId());
new Handler(Looper.getMainLooper()).post(() -> {
try {
Uri videoUri = Uri.parse(videoUrl);
Log.d(TAG, "Setting video URI after delay");
videoView.setVideoURI(videoUri);
videoView.requestFocus();
if (videoView.hasFocus()) {
Log.d(TAG, "The VideoView successfully received focus");
} else {
Log.d(TAG, "The VideoView did not receive focus");
}
} catch (Exception e) {
Log.e(TAG, "Invalid video source: " + videoUrl, e);
}
});
}
@Override
public void onDropViewInstance(@NonNull VideoView videoView) {
if (videoView.hasFocus()) {
Log.d(TAG, "DROPPING VideoView successfully received focus");
} else {
Log.d(TAG, "DROPPING VideoView did not receive focus");
}
VideoView v2 = new VideoView(videoView.getContext());
Log.d(TAG, "Dropping video VIEW ID: " + videoView.getId() + " " + v2.getId());
super.onDropViewInstance(videoView);
// Retrieve the URI that was set
Uri currentUri = (Uri) videoView.getTag();
if (currentUri != null) {
Log.d(TAG, "VideoView removed. Last video URI: " + currentUri.toString());
} else {
Log.d(TAG, "VideoView removed. No URI was set.");
}
// Perform cleanup
videoView.stopPlayback();
videoView.setOnPreparedListener(null);
videoView.setOnErrorListener(null);
videoView.setOnCompletionListener(null);
}
}
I am also sure that the View is still on the stack because onDropViewInstance
instance is triggered only when I hit the back button and the return value for getId()
matches as well.
React Native Version: 0.76.3
Tested with both new architecture
enabled and disabled.
I tried out the code in Native Android Project and it works fine. The listeners are triggered as expected. The url used is same in either case.
I am expecting the listeners to be triggered in a React Native Environment.
I want to avoid the use of third party libraries like react-native-video
as much as possible.
Upvotes: 0
Views: 20