|
|
|
|
|
|
|
|
package com.example.ueberwachungssystem.Detection; |
|
|
package com.example.ueberwachungssystem.Detection; |
|
|
|
|
|
|
|
|
|
|
|
import android.Manifest; |
|
|
|
|
|
import android.annotation.SuppressLint; |
|
|
import android.content.Context; |
|
|
import android.content.Context; |
|
|
|
|
|
import android.content.pm.PackageManager; |
|
|
import android.graphics.ImageFormat; |
|
|
import android.graphics.ImageFormat; |
|
|
import android.media.Image; |
|
|
import android.media.Image; |
|
|
import android.util.Size; |
|
|
import android.util.Size; |
|
|
|
|
|
import android.view.Surface; |
|
|
|
|
|
import android.widget.Toast; |
|
|
|
|
|
import android.widget.VideoView; |
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull; |
|
|
import androidx.annotation.NonNull; |
|
|
|
|
|
import androidx.annotation.Nullable; |
|
|
import androidx.camera.core.CameraSelector; |
|
|
import androidx.camera.core.CameraSelector; |
|
|
import androidx.camera.core.ExperimentalGetImage; |
|
|
import androidx.camera.core.ExperimentalGetImage; |
|
|
import androidx.camera.core.ImageAnalysis; |
|
|
import androidx.camera.core.ImageAnalysis; |
|
|
import androidx.camera.core.Preview; |
|
|
import androidx.camera.core.Preview; |
|
|
|
|
|
import androidx.camera.core.VideoCapture; |
|
|
import androidx.camera.lifecycle.ProcessCameraProvider; |
|
|
import androidx.camera.lifecycle.ProcessCameraProvider; |
|
|
import androidx.camera.view.PreviewView; |
|
|
import androidx.camera.view.PreviewView; |
|
|
|
|
|
import androidx.core.app.ActivityCompat; |
|
|
import androidx.core.content.ContextCompat; |
|
|
import androidx.core.content.ContextCompat; |
|
|
import androidx.lifecycle.LifecycleOwner; |
|
|
import androidx.lifecycle.LifecycleOwner; |
|
|
|
|
|
|
|
|
import com.google.common.util.concurrent.ListenableFuture; |
|
|
import com.google.common.util.concurrent.ListenableFuture; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
import java.nio.ByteBuffer; |
|
|
import java.nio.ByteBuffer; |
|
|
import java.util.concurrent.ExecutionException; |
|
|
import java.util.concurrent.ExecutionException; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Boolean isDetectionRunning = false; |
|
|
private Boolean isDetectionRunning = false; |
|
|
// Preview Camera Image |
|
|
// Preview Camera Image |
|
|
private PreviewView previewView = null; |
|
|
private PreviewView previewView = null; |
|
|
|
|
|
private VideoCapture videoCapture = null; |
|
|
// Detect Violation |
|
|
// Detect Violation |
|
|
private static final float PIXEL_THRESHOLD = 30f; // Luminosity (brightness channel of YUV_420_888) |
|
|
private static final float PIXEL_THRESHOLD = 30f; // Luminosity (brightness channel of YUV_420_888) |
|
|
private static final float ALARM_THRESHOLD = 0.2f; // Percent of pixels changed |
|
|
private static final float ALARM_THRESHOLD = 0.2f; // Percent of pixels changed |
|
|
private ByteBuffer previousBuffer = null; |
|
|
private ByteBuffer previousBuffer = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Constructor |
|
|
* Constructor |
|
|
* @param context: the context of calling activity (usually "this") |
|
|
* @param context: the context of calling activity (usually "this") |
|
|
|
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) { |
|
|
} catch (ExecutionException | InterruptedException e) { |
|
|
// No errors need to be handled for this Future. This should never be reached. |
|
|
// No errors need to be handled for this Future. This should never be reached. |
|
|
} |
|
|
} |
|
|
},ContextCompat.getMainExecutor(context)); |
|
|
|
|
|
|
|
|
}, ContextCompat.getMainExecutor(context)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* Binds the Luminosity Analyzer (configure and run Analysis) |
|
|
* Binds the Luminosity Analyzer (configure and run Analysis) |
|
|
* @param cameraProvider: CameraProvider of Context passed by Constructor |
|
|
* @param cameraProvider: CameraProvider of Context passed by Constructor |
|
|
* */ |
|
|
* */ |
|
|
|
|
|
@SuppressLint("RestrictedApi") |
|
|
private void bindAnalysis(@NonNull ProcessCameraProvider cameraProvider) { |
|
|
private void bindAnalysis(@NonNull ProcessCameraProvider cameraProvider) { |
|
|
// Configure and create Image Analysis |
|
|
// Configure and create Image Analysis |
|
|
ImageAnalysis.Builder builder = new ImageAnalysis.Builder(); |
|
|
ImageAnalysis.Builder builder = new ImageAnalysis.Builder(); |
|
|
|
|
|
|
|
|
if (previewView != null) |
|
|
if (previewView != null) |
|
|
preview.setSurfaceProvider(previewView.getSurfaceProvider()); |
|
|
preview.setSurfaceProvider(previewView.getSurfaceProvider()); |
|
|
|
|
|
|
|
|
cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, imageAnalysis, preview); |
|
|
|
|
|
|
|
|
videoCapture = new VideoCapture.Builder() |
|
|
|
|
|
.setVideoFrameRate(30) |
|
|
|
|
|
.setTargetRotation(Surface.ROTATION_0) |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, imageAnalysis, videoCapture); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressLint("RestrictedApi") |
|
|
|
|
|
public void startRecording() { |
|
|
|
|
|
|
|
|
|
|
|
File dir = context.getFilesDir(); |
|
|
|
|
|
String filename = "recording"; |
|
|
|
|
|
String vidFilePath = dir.getAbsolutePath() + "/" + filename + ".mp4"; |
|
|
|
|
|
File vidFile = new File(vidFilePath); |
|
|
|
|
|
|
|
|
|
|
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { |
|
|
|
|
|
// TODO: Consider calling |
|
|
|
|
|
// ActivityCompat#requestPermissions |
|
|
|
|
|
// here to request the missing permissions, and then overriding |
|
|
|
|
|
// public void onRequestPermissionsResult(int requestCode, String[] permissions, |
|
|
|
|
|
// int[] grantResults) |
|
|
|
|
|
// to handle the case where the user grants the permission. See the documentation |
|
|
|
|
|
// for ActivityCompat#requestPermissions for more details. |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
videoCapture.startRecording( |
|
|
|
|
|
new VideoCapture.OutputFileOptions.Builder(vidFile).build(), |
|
|
|
|
|
context.getMainExecutor(), |
|
|
|
|
|
new VideoCapture.OnVideoSavedCallback() { |
|
|
|
|
|
@Override |
|
|
|
|
|
public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) { |
|
|
|
|
|
Toast.makeText(context, "recording saved", Toast.LENGTH_SHORT).show(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) { |
|
|
|
|
|
Toast.makeText(context, "recording failed", Toast.LENGTH_SHORT).show(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressLint("RestrictedApi") |
|
|
|
|
|
public void stopRecording(){ |
|
|
|
|
|
videoCapture.stopRecording(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Calculate Amount of Pixels changed using a threshold |
|
|
* Calculate Amount of Pixels changed using a threshold |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return changedPixelCount; |
|
|
return changedPixelCount; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void playVideo(VideoView videoView) { |
|
|
|
|
|
videoView.setVideoPath(context.getFilesDir() + "/recording.mp4"); |
|
|
|
|
|
videoView.start(); |
|
|
|
|
|
} |
|
|
} |
|
|
} |