added video api support in java

This commit is contained in:
Mautisim Munir 2022-11-10 00:02:09 +05:00
parent e1b867c420
commit 208752d58e
4 changed files with 110 additions and 28 deletions

View File

@ -33,9 +33,8 @@ import androidx.appcompat.app.AppCompatActivity;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.google.mediapipe.R; import com.google.mediapipe.R;
import com.google.mediapipe.solutions.lindera.BodyJoints;
import com.google.mediapipe.solutions.lindera.CameraRotation; import com.google.mediapipe.solutions.lindera.CameraRotation;
import com.google.mediapipe.solutions.lindera.ComputerVisionPlugin; import com.google.mediapipe.solutions.lindera.InputSource;
import com.google.mediapipe.solutions.lindera.Lindera; import com.google.mediapipe.solutions.lindera.Lindera;
import org.json.JSONException; import org.json.JSONException;
@ -80,11 +79,11 @@ public class MainActivity extends AppCompatActivity {
lindera = new Lindera(plugin); lindera = new Lindera(plugin);
lindera.setupVideoPicker(this);
List<String> cameras = lindera.getAvailableCameras(); List<String> cameras = lindera.getAvailableCameras();
// FRONT or BACK // FRONT or BACK
lindera.setCamera("FRONT"); lindera.setCamera("FRONT");
lindera.setCameraRotation(CameraRotation.AUTOMATIC); lindera.setCameraRotation(CameraRotation.AUTOMATIC);
lindera.fpsHelper.onFpsUpdate = new Consumer<Double>() { lindera.fpsHelper.onFpsUpdate = new Consumer<Double>() {
@Override @Override
public void accept(Double fps) { public void accept(Double fps) {
@ -99,36 +98,55 @@ public class MainActivity extends AppCompatActivity {
} }
private void startDetectionPipeline(InputSource inputSource){
if (!isLinderaInitialized) {
modelLoadAsyncDialogue(()->{
if (inputSource==InputSource.VIDEO){
lindera.setInputSource(InputSource.VIDEO);
}
lindera.initialize(findViewById(R.id.preview_display_layout), MainActivity.this);
isLinderaInitialized = true;
findViewById(R.id.button_start_video).setVisibility(View.GONE);
findViewById(R.id.button_start_camera).setVisibility(View.GONE);
findViewById(R.id.button_set_model).setVisibility(View.VISIBLE);
findViewById(R.id.button_toggle_landmarks).setVisibility(View.VISIBLE);
findViewById(R.id.button_capture_logging).setVisibility(View.VISIBLE);
updateLandmarkButtonText();
updateModelComplexityButtonText();
if (inputSource==InputSource.VIDEO) {
lindera.pickVideo();
}
});
}
isDetectionStarted = !isDetectionStarted;
}
/** /**
* Sets up the UI components for the live demo with camera input. * Sets up the UI components for the live demo with camera input.
*/ */
private void setupLiveDemoUiComponents() { private void setupLiveDemoUiComponents() {
Button startDetectionButton = findViewById(R.id.button_start_detection); Button startCameraButton = findViewById(R.id.button_start_camera);
Button startVideoButton = findViewById(R.id.button_start_video);
Button toggleLandmarks = findViewById(R.id.button_toggle_landmarks); Button toggleLandmarks = findViewById(R.id.button_toggle_landmarks);
Button modelComplexity = findViewById(R.id.button_set_model); Button modelComplexity = findViewById(R.id.button_set_model);
Button startCapture = findViewById(R.id.button_capture_logging); Button startCapture = findViewById(R.id.button_capture_logging);
FrameLayout frameLayout = findViewById(R.id.preview_display_layout); FrameLayout frameLayout = findViewById(R.id.preview_display_layout);
startDetectionButton.setOnClickListener( startCameraButton.setOnClickListener(
v -> { v -> {
// startCameraButton.setVisibility(View.GONE); startDetectionPipeline(InputSource.CAMERA);
if (!isLinderaInitialized) {
modelLoadAsyncDialogue(()->{
lindera.initialize(frameLayout, MainActivity.this);
isLinderaInitialized = true;
startDetectionButton.setVisibility(View.GONE);
findViewById(R.id.button_set_model).setVisibility(View.VISIBLE);
findViewById(R.id.button_toggle_landmarks).setVisibility(View.VISIBLE);
findViewById(R.id.button_capture_logging).setVisibility(View.VISIBLE);
updateLandmarkButtonText();
updateModelComplexityButtonText();
});
}
isDetectionStarted = !isDetectionStarted; });
startVideoButton.setOnClickListener(
v -> {
startDetectionPipeline(InputSource.VIDEO);
}); });

View File

@ -15,11 +15,18 @@
android:orientation="horizontal"> android:orientation="horizontal">
<Button <Button
android:id="@+id/button_start_detection" android:id="@+id/button_start_camera"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Start Detection" /> android:text="Start Camera" />
<Button
android:id="@+id/button_start_video"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Video" />
<Button <Button
android:id="@+id/button_toggle_landmarks" android:id="@+id/button_toggle_landmarks"

View File

@ -0,0 +1,5 @@
package com.google.mediapipe.solutions.lindera;
public enum InputSource {
VIDEO, CAMERA
}

View File

@ -1,15 +1,21 @@
package com.google.mediapipe.solutions.lindera; package com.google.mediapipe.solutions.lindera;
import android.app.Activity;
import android.content.Intent;
import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.mediapipe.formats.proto.LandmarkProto; import com.google.mediapipe.formats.proto.LandmarkProto;
import com.google.mediapipe.solutioncore.CameraInput; import com.google.mediapipe.solutioncore.CameraInput;
import com.google.mediapipe.solutioncore.SolutionGlSurfaceView; import com.google.mediapipe.solutioncore.SolutionGlSurfaceView;
import com.google.mediapipe.solutioncore.VideoInput;
import com.google.mediapipe.solutions.posetracking.PoseTracking; import com.google.mediapipe.solutions.posetracking.PoseTracking;
import com.google.mediapipe.solutions.posetracking.PoseTrackingOptions; import com.google.mediapipe.solutions.posetracking.PoseTrackingOptions;
import com.google.mediapipe.solutions.posetracking.PoseTrackingResult; import com.google.mediapipe.solutions.posetracking.PoseTrackingResult;
@ -24,7 +30,7 @@ public class Lindera {
private ComputerVisionPlugin plugin; private ComputerVisionPlugin plugin;
public FpsHelper fpsHelper = new FpsHelper(); public FpsHelper fpsHelper = new FpsHelper();
private PoseTracking poseTracking; private PoseTracking poseTracking;
private InputSource inputSource = InputSource.CAMERA;
private CameraRotation cameraRotation = CameraRotation.AUTOMATIC; private CameraRotation cameraRotation = CameraRotation.AUTOMATIC;
// Live camera demo UI and camera components. // Live camera demo UI and camera components.
@ -34,7 +40,9 @@ public class Lindera {
private AppCompatActivity appCompatActivity; private AppCompatActivity appCompatActivity;
private ViewGroup computerVisionContainerView; private ViewGroup computerVisionContainerView;
private PoseTrackingResultGlRenderer solutionRenderer; private PoseTrackingResultGlRenderer solutionRenderer;
private VideoInput videoInput;
private ActivityResultLauncher<Intent> videoGetter;
public Lindera(ComputerVisionPlugin plugin){ public Lindera(ComputerVisionPlugin plugin){
this.plugin = plugin; this.plugin = plugin;
} }
@ -72,13 +80,41 @@ public class Lindera {
this.computerVisionContainerView = computerVisionContainerView; this.computerVisionContainerView = computerVisionContainerView;
this.appCompatActivity = appCompatActivity; this.appCompatActivity = appCompatActivity;
startDetection(); startDetection();
} }
public void setCameraRotation(CameraRotation cameraRotation){ public void setCameraRotation(CameraRotation cameraRotation){
this.cameraRotation = cameraRotation; this.cameraRotation = cameraRotation;
} }
public void setInputSource(InputSource source){
this.inputSource = source;
}
/**
* Required for picking videos
* @param appCompatActivity
*/
public void setupVideoPicker(AppCompatActivity appCompatActivity){
videoGetter =
appCompatActivity.registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
Intent resultIntent = result.getData();
if (resultIntent != null) {
if (result.getResultCode() == Activity.RESULT_OK) {
glSurfaceView.post(
() ->
videoInput.start(
appCompatActivity,
resultIntent.getData(),
poseTracking.getGlContext(),
glSurfaceView.getWidth(),
glSurfaceView.getHeight()));
}
}
});
}
private void setupEventListener() { private void setupEventListener() {
poseTracking.setResultListener( poseTracking.setResultListener(
poseTrackingResult -> { poseTrackingResult -> {
@ -132,6 +168,12 @@ public class Lindera {
); );
} }
public void pickVideo(){
inputSource = InputSource.VIDEO;
Intent pickVideoIntent = new Intent(Intent.ACTION_PICK);
pickVideoIntent.setDataAndType(MediaStore.Video.Media.INTERNAL_CONTENT_URI, "video/*");
videoGetter.launch(pickVideoIntent);
}
public void startDetection(PoseTrackingOptions options){ public void startDetection(PoseTrackingOptions options){
// ensure that class is initalized // ensure that class is initalized
assert (appCompatActivity != null); assert (appCompatActivity != null);
@ -142,10 +184,14 @@ public class Lindera {
options); options);
poseTracking.setErrorListener( poseTracking.setErrorListener(
(message, e) -> Log.e("Lindera", "MediaPipe Pose Tracking error:" + message)); (message, e) -> Log.e("Lindera", "MediaPipe Pose Tracking error:" + message));
cameraInput = new CameraInput(appCompatActivity); if (inputSource==InputSource.CAMERA) {
cameraInput = new CameraInput(appCompatActivity);
cameraInput.setNewFrameListener(textureFrame -> poseTracking.send(textureFrame));
cameraInput.setNewFrameListener(textureFrame -> poseTracking.send(textureFrame));
}else if (inputSource==InputSource.VIDEO){
videoInput = new VideoInput(appCompatActivity);
videoInput.setNewFrameListener(textureFrame -> poseTracking.send(textureFrame));
}
// Initializes a new Gl surface view with a user-defined PoseTrackingResultGlRenderer. // Initializes a new Gl surface view with a user-defined PoseTrackingResultGlRenderer.
glSurfaceView = glSurfaceView =
new SolutionGlSurfaceView<>( new SolutionGlSurfaceView<>(
@ -162,7 +208,9 @@ public class Lindera {
// The runnable to start camera after the gl surface view is attached. // The runnable to start camera after the gl surface view is attached.
// For video input source, videoInput.start() will be called when the video uri is available. // For video input source, videoInput.start() will be called when the video uri is available.
glSurfaceView.post(this::startCamera); if (inputSource==InputSource.CAMERA) {
glSurfaceView.post(this::startCamera);
}
// Updates the preview layout. // Updates the preview layout.
computerVisionContainerView.removeAllViewsInLayout(); computerVisionContainerView.removeAllViewsInLayout();
@ -179,6 +227,10 @@ public class Lindera {
if (glSurfaceView != null) { if (glSurfaceView != null) {
glSurfaceView.setVisibility(View.GONE); glSurfaceView.setVisibility(View.GONE);
} }
if (videoInput != null) {
videoInput.setNewFrameListener(null);
videoInput.close();
}
if (poseTracking != null) { if (poseTracking != null) {
poseTracking.close(); poseTracking.close();
} }