diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/AudioRecorder.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/AudioRecorder.java index 0abe0f5..e794c72 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/AudioRecorder.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/AudioRecorder.java @@ -69,15 +69,4 @@ public class AudioRecorder { // Return the timestamp as a string return currentTime.format(formatter); } - - public void playAudio() { - MediaPlayer mp = new MediaPlayer(); - try { - mp.setDataSource(context.getFilesDir() + "/audio.3gp"); - mp.prepare(); - mp.start(); - } catch (Exception e) { - e.printStackTrace(); - } - } } diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/Detector.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/Detector.java index c8ad62c..826878b 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/Detector.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/Detector.java @@ -12,7 +12,7 @@ abstract public class Detector { private boolean extendViolation = false; // Countdown parameters - private final int COUNTDOWN_TIME = 5000; // milliseconds + private final int COUNTDOWN_TIME = 10000; // milliseconds private final int COUNTDOWN_POLLING_TIME = 100; // milliseconds /** Constructor - takes context of current activity */ diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java index 3925962..9c0ebda 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java @@ -6,13 +6,10 @@ import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.ImageFormat; -import android.graphics.Rect; -import android.hardware.SensorManager; import android.media.Image; import android.os.CountDownTimer; import android.util.Log; import android.view.Display; -import android.view.OrientationEventListener; import android.view.Surface; import android.view.WindowManager; import android.widget.ImageView; @@ -20,7 +17,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.camera.core.AspectRatio; import androidx.camera.core.CameraSelector; import androidx.camera.core.ExperimentalGetImage; import androidx.camera.core.ImageAnalysis; @@ -54,7 +50,6 @@ import java.util.concurrent.ExecutionException; @ExperimentalGetImage public class VideoDetector extends Detector { - // Calling Activity private final Context context; @@ -65,7 +60,7 @@ public class VideoDetector extends Detector { private ProcessCameraProvider cameraProvider; private ImageAnalysis imageAnalysis; private VideoCapture videoCapture; - private final Preview preview; + //private Preview preview; // Logic private boolean isDetecting = false; @@ -79,21 +74,17 @@ public class VideoDetector extends Detector { private ImageView inputImageView = null; private ImageView outputImageView = null; + // Recorder + private File outputDir; // Default: in app files directory private int rotation = 0; // Parameters private static final float ALARM_THRESHOLD = 0.5f; // Percent of pixels changed - private static final long START_DELAY = 20000; // milliseconds + private static final float START_DELAY = 20000; // milliseconds private static final android.util.Size IMAGE_RES = new android.util.Size(640, 480); - private enum UseCase { - ImageAnalysis, - Preview, - VideoCapture - }; - /** Constructor */ public VideoDetector(Context context) { @@ -101,7 +92,8 @@ public class VideoDetector extends Detector { this.context = context; this.imageAnalysis = setupImageAnalysis(); this.videoCapture = setupVideoCapture(); - this.preview = new Preview.Builder().build(); + this.outputDir = context.getFilesDir(); + //this.preview = new Preview.Builder().build(); } /** Get States */ @@ -124,9 +116,8 @@ public class VideoDetector extends Detector { getPermissions(); return; } - + // Configure Image Analysis imageAnalysis = setupImageAnalysis(); - // Open CV startup check if (!OpenCVLoader.initDebug()) { Log.e("OpenCV", "Unable to load OpenCV!"); @@ -139,11 +130,58 @@ public class VideoDetector extends Detector { try { cameraProvider = cameraProviderFuture.get(); isDetecting = true; - bindCameraProvider(UseCase.ImageAnalysis); + bindCameraProvider(); } catch (ExecutionException | InterruptedException e) {} }, ContextCompat.getMainExecutor(context)); + // Disable Violation Calling for Setup Time + startViolationTimer(START_DELAY); + } - startViolationTimer(); + /** Starts the Recorder */ + @SuppressLint("RestrictedApi") + public void startRecording() { + // Check States + if (isRecording){ + extendViolation(); + return; + } + // Return On Request Permissions + if (!hasPermissions()) { + getPermissions(); + return; + } + + videoCapture = setupVideoCapture(); + + final ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(context); + cameraProviderFuture.addListener(() -> { + try { + cameraProvider = cameraProviderFuture.get(); + isRecording = true; + bindCameraProvider(); + + File vidFile = new File(context.getFilesDir() + "/" + generateFileName() + ".mp4"); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { + return; + } + videoCapture.startRecording( + new VideoCapture.OutputFileOptions.Builder(vidFile).build(), + context.getMainExecutor(), + new VideoCapture.OnVideoSavedCallback() { + @Override + public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) { + isRecording = false; + Toast.makeText(context, "recording saved", Toast.LENGTH_SHORT).show(); + } + @Override + public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) { + isRecording = false; + Toast.makeText(context, "recording failed", Toast.LENGTH_SHORT).show(); + } + } + ); + } catch (ExecutionException | InterruptedException ignored) {} + }, ContextCompat.getMainExecutor(context)); } /** Stops the Video Detection */ @@ -156,41 +194,22 @@ public class VideoDetector extends Detector { allowReportViolation = false; } - /** Permission handling */ - private boolean hasPermissions() { - return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; - } - private void getPermissions() { - if (!hasPermissions()) - ActivityCompat.requestPermissions((Activity) context, new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE); + /** Stops the Recording */ + @SuppressLint("RestrictedApi") + public void stopRecording(){ + videoCapture.stopRecording(); + cameraProvider.unbind(videoCapture); + isRecording = false; } - - - /** Binds the Luminosity Analyzer (configure and run Analysis) */ - private void bindCameraProvider(UseCase useCase) { + /** Bind Camera Provider */ + private void bindCameraProvider() { // Specify which Camera to use CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build(); cameraProvider.unbindAll(); cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, imageAnalysis, videoCapture); } - - /** Start delay until Violation Report is allowed */ - private void startViolationTimer() { - new CountDownTimer((long) (START_DELAY), 100) { - @Override - public void onTick(long millisUntilFinished) { - } - @Override - public void onFinish() { - allowReportViolation = true; - } - }.start(); - } - - /** Setup Use Cases */ private ImageAnalysis setupImageAnalysis() { // Configure and create Image Analysis @@ -226,114 +245,63 @@ public class VideoDetector extends Detector { @SuppressLint("RestrictedApi") private VideoCapture setupVideoCapture() { - int rotation = getRotation(); + int rotation = getDisplayRotation(); return new VideoCapture.Builder() .setTargetRotation(rotation) .build(); } - @SuppressLint("RestrictedApi") - public void startRecording() { - // Check States - if (isRecording){ - extendViolation(); - return; - } - // Return On Request Permissions - if (!hasPermissions()) { - getPermissions(); - return; - } - - videoCapture = setupVideoCapture(); - - final ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(context); - cameraProviderFuture.addListener(() -> { - try { - cameraProvider = cameraProviderFuture.get(); - isRecording = true; - bindCameraProvider(UseCase.VideoCapture); - - File vidFile = new File(context.getFilesDir() + "/" + generateFileName() + ".mp4"); - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { - return; - } - videoCapture.startRecording( - new VideoCapture.OutputFileOptions.Builder(vidFile).build(), - context.getMainExecutor(), - new VideoCapture.OnVideoSavedCallback() { - @Override - public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) { - isRecording = false; - Toast.makeText(context, "recording saved", Toast.LENGTH_SHORT).show(); - } - @Override - public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) { - isRecording = false; - Toast.makeText(context, "recording failed", Toast.LENGTH_SHORT).show(); - } - } - ); - } catch (ExecutionException | InterruptedException ignored) {} - }, ContextCompat.getMainExecutor(context)); - } - - @SuppressLint("RestrictedApi") - public void stopRecording(){ - videoCapture.stopRecording(); - cameraProvider.unbind(videoCapture); - isRecording = false; - } - /** Process Image to be used for Motion Detection */ private Mat processImage(ImageProxy imageProxy){ if (imageProxy == null) return null; - // Image Transformation Mat imageMat = OpenCVHelper.extractYChannel(imageProxy); - // Show Input Image if (inputImageView != null) OpenCVHelper.debugMat(imageMat, inputImageView); - // Preprocess Image Mat preprocessed = imageMat; preprocessed = OpenCVHelper.addGaussianBlur(preprocessed, new Size(21, 21)); preprocessed = OpenCVHelper.addBlur(preprocessed, new Size(3, 3)); - + // Set Previous Image if (previousImage == null) { previousImage = preprocessed; return null; } - // Process Image Mat processed = preprocessed.clone(); processed = OpenCVHelper.thresholdPixels(processed, previousImage, 25); processed = OpenCVHelper.dilateBinaryMat(processed, new Size(3,3)); processed = OpenCVHelper.dilateBinaryMat(processed, new Size(3,3)); processed = OpenCVHelper.thresholdContourArea(processed, 500); - // Output previousImage = preprocessed.clone(); // Show Output Image if (outputImageView != null) OpenCVHelper.debugMat(processed, outputImageView); - return processed; } + + /** Debug input and result of processing */ public void debugProcessing(@NonNull ImageView inputImageView, @NonNull ImageView outputImageView){ this.inputImageView = inputImageView; this.outputImageView = outputImageView; } - public void setPreviewView(@NonNull PreviewView previewView) { + + /** + private void setPreviewView(@NonNull PreviewView previewView) { // Create Preview if (this.preview != null) this.preview.setSurfaceProvider(previewView.getSurfaceProvider()); } + */ + + + /** Generate File Name */ private String generateFileName(){ // Get the current timestamp LocalDateTime currentTime = LocalDateTime.now(); @@ -343,9 +311,39 @@ public class VideoDetector extends Detector { return currentTime.format(formatter); } - private int getRotation() { + + /** Get current Display Rotation */ + private int getDisplayRotation() { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); return display.getRotation(); } + + + /** Start delay until Violation Report is allowed */ + private void startViolationTimer(float setupTime) { + new CountDownTimer((long) (START_DELAY), 100) { + @Override + public void onTick(long millisUntilFinished) { + } + @Override + public void onFinish() { + allowReportViolation = true; + } + }.start(); + } + + /** Permission handling */ + private boolean hasPermissions() { + return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; + } + private void getPermissions() { + if (!hasPermissions()) + ActivityCompat.requestPermissions((Activity) context, new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE); + } + + public void setOutputDir(File outputDir) { + this.outputDir = outputDir; + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java index 72fbefe..a75571b 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java +++ b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java @@ -37,6 +37,10 @@ public class MainActivity extends AppCompatActivity { @Override public void onDetection(@NonNull DetectionReport detectionReport) { Log.d("onDetection", detectionReport.toString()); + if (detectionReport.detectionState) + vd.startRecording(); + else + vd.stopRecording(); } }); vd.startDetection(); @@ -54,7 +58,7 @@ public class MainActivity extends AppCompatActivity { { //vd.startDetection(); vd.stopDetection(); - vd.startRecording(); + //vd.startRecording(); audioRecorder.startRecording(); } else {