From 4a542be54d992101de40e1487aa08f95df4ac671 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 12 Jun 2016 19:58:39 +0200 Subject: [PATCH] implement video recording --- app/src/main/AndroidManifest.xml | 1 + .../camera/MainActivity.java | 34 ++++++- .../camera/PhotoProcessor.java | 30 +----- .../com/simplemobiletools/camera/Preview.java | 89 +++++++++++++++++- .../com/simplemobiletools/camera/Utils.java | 41 ++++++++ app/src/main/res/mipmap-hdpi/video_stop.png | Bin 0 -> 1574 bytes app/src/main/res/mipmap-mdpi/video_stop.png | Bin 0 -> 933 bytes app/src/main/res/mipmap-xhdpi/video_stop.png | Bin 0 -> 1978 bytes app/src/main/res/mipmap-xxhdpi/video_stop.png | Bin 0 -> 3944 bytes .../main/res/mipmap-xxxhdpi/video_stop.png | Bin 0 -> 4212 bytes app/src/main/res/values/strings.xml | 3 + 11 files changed, 165 insertions(+), 33 deletions(-) create mode 100644 app/src/main/res/mipmap-hdpi/video_stop.png create mode 100644 app/src/main/res/mipmap-mdpi/video_stop.png create mode 100644 app/src/main/res/mipmap-xhdpi/video_stop.png create mode 100644 app/src/main/res/mipmap-xxhdpi/video_stop.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/video_stop.png diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4f9de630..26bcfe37 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ android:name="android.hardware.camera" android:required="true"/> + diff --git a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java index e405f175..ce68dc2f 100644 --- a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java @@ -87,7 +87,15 @@ public class MainActivity extends AppCompatActivity implements SensorEventListen if (isPhoto) { preview.takePicture(); } else { - + final Resources res = getResources(); + final boolean isRecording = preview.toggleRecording(); + if (isRecording) { + shutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_stop)); + toggleCameraBtn.setVisibility(View.INVISIBLE); + } else { + shutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_rec)); + toggleCameraBtn.setVisibility(View.VISIBLE); + } } } @@ -99,18 +107,27 @@ public class MainActivity extends AppCompatActivity implements SensorEventListen @OnClick(R.id.toggle_videocam) public void toggleVideo() { - final Resources res = getResources(); isPhoto = !isPhoto; + toggleCameraBtn.setVisibility(View.VISIBLE); if (isPhoto) { + final Resources res = getResources(); togglePhotoVideoBtn.setImageDrawable(res.getDrawable(R.mipmap.videocam)); shutterBtn.setImageDrawable(res.getDrawable(R.mipmap.camera)); + preview.initPhotoMode(); } else { - togglePhotoVideoBtn.setImageDrawable(res.getDrawable(R.mipmap.photo)); - shutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_rec)); + initVideo(); } } + private void initVideo() { + final Resources res = getResources(); + togglePhotoVideoBtn.setImageDrawable(res.getDrawable(R.mipmap.photo)); + shutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_rec)); + preview.initRecorder(); + toggleCameraBtn.setVisibility(View.VISIBLE); + } + private void hideNavigationBarIcons() { getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); } @@ -130,12 +147,19 @@ public class MainActivity extends AppCompatActivity implements SensorEventListen final Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME); } + + if (!isPhoto) { + preview.initRecorder(); + initVideo(); + } } @Override protected void onPause() { super.onPause(); - preview.releaseCamera(); + if (preview != null) { + preview.releaseCamera(); + } if (sensorManager != null) sensorManager.unregisterListener(this); diff --git a/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java b/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java index 85f88bc2..f68008e7 100644 --- a/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java +++ b/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java @@ -6,17 +6,13 @@ import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.hardware.Camera; import android.media.ExifInterface; -import android.media.MediaScannerConnection; import android.os.AsyncTask; -import android.os.Environment; import android.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; public class PhotoProcessor extends AsyncTask { private static final String TAG = PhotoProcessor.class.getSimpleName(); @@ -30,12 +26,13 @@ public class PhotoProcessor extends AsyncTask { @Override protected Void doInBackground(byte[]... params) { - final File photoFile = getOutputMediaFile(); - if (photoFile == null) { + final String photoPath = Utils.getOutputMediaFile(mContext, true); + if (photoPath.isEmpty()) { return null; } try { + final File photoFile = new File(photoPath); final byte[] data = params[0]; final FileOutputStream fos = new FileOutputStream(photoFile); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); @@ -45,7 +42,7 @@ public class PhotoProcessor extends AsyncTask { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.close(); - scanPhoto(photoFile); + Utils.scanFile(photoPath, mContext); } catch (FileNotFoundException e) { Log.d(TAG, "onPictureTaken file not found: " + e.getMessage()); } catch (IOException e) { @@ -55,20 +52,6 @@ public class PhotoProcessor extends AsyncTask { return null; } - private static File getOutputMediaFile() { - final String appName = mContext.getResources().getString(R.string.app_name); - final File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appName); - - if (!mediaStorageDir.exists()) { - if (!mediaStorageDir.mkdirs()) { - return null; - } - } - - final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); - return new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); - } - private Bitmap setBitmapRotation(Bitmap bitmap, String path) throws IOException { final ExifInterface exif = new ExifInterface(path); final String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION); @@ -127,9 +110,4 @@ public class PhotoProcessor extends AsyncTask { } return bitmap; } - - private void scanPhoto(File photo) { - final String[] photoPath = {photo.getAbsolutePath()}; - MediaScannerConnection.scanFile(mContext, photoPath, null, null); - } } diff --git a/app/src/main/java/com/simplemobiletools/camera/Preview.java b/app/src/main/java/com/simplemobiletools/camera/Preview.java index aa7ddb54..f7432fa0 100644 --- a/app/src/main/java/com/simplemobiletools/camera/Preview.java +++ b/app/src/main/java/com/simplemobiletools/camera/Preview.java @@ -4,7 +4,9 @@ import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.hardware.Camera; +import android.media.CamcorderProfile; import android.media.MediaPlayer; +import android.media.MediaRecorder; import android.os.Handler; import android.util.Log; import android.view.MotionEvent; @@ -34,6 +36,11 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O private static boolean isFlashEnabled; private static Camera.Parameters parameters; + private static MediaRecorder recorder; + private static boolean isRecording; + private static boolean isVideoMode; + private static String curVideoPath; + public Preview(Context context) { super(context); } @@ -68,7 +75,6 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O releaseCamera(); camera = newCamera; - if (camera != null) { parameters = camera.getParameters(); supportedPreviewSizes = parameters.getSupportedPreviewSizes(); @@ -90,6 +96,9 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O setupPreview(); } } + + if (isVideoMode) + initRecorder(); } public static void setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) { @@ -141,8 +150,9 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O new Handler().postDelayed(new Runnable() { @Override public void run() { - if (camera != null) + if (camera != null) { camera.startPreview(); + } canTakePicture = true; } @@ -200,6 +210,8 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O } public void releaseCamera() { + stopRecording(); + if (camera != null) { camera.stopPreview(); camera.release(); @@ -240,6 +252,19 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O if (camera != null) { camera.stopPreview(); } + + cleanupRecorder(); + } + + private void cleanupRecorder() { + if (recorder != null) { + if (isRecording) { + recorder.stop(); + } + + recorder.release(); + recorder = null; + } } @Override @@ -307,4 +332,64 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O public void disableFlash() { isFlashEnabled = false; } + + public void initPhotoMode() { + isRecording = false; + isVideoMode = false; + stopRecording(); + cleanupRecorder(); + } + + // VIDEO RECORDING + public void initRecorder() { + isRecording = false; + isVideoMode = true; + recorder = new MediaRecorder(); + recorder.setCamera(camera); + recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); + recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); + + curVideoPath = Utils.getOutputMediaFile(getContext(), false); + if (curVideoPath.isEmpty()) { + Utils.showToast(getContext(), R.string.video_creating_error); + return; + } + + final CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH); + recorder.setProfile(cpHigh); + recorder.setOutputFile(curVideoPath); + recorder.setPreviewDisplay(surfaceHolder.getSurface()); + recorder.setOrientationHint(90); + + try { + recorder.prepare(); + } catch (IllegalStateException e) { + Log.e(TAG, "initRecorder " + e.getMessage()); + } catch (IOException e) { + Log.e(TAG, "initRecorder " + e.getMessage()); + } + } + + public boolean toggleRecording() { + if (isRecording) { + stopRecording(); + initRecorder(); + } else { + camera.lock(); + camera.unlock(); + recorder.start(); + isRecording = true; + } + return isRecording; + } + + private void stopRecording() { + if (recorder != null && isRecording) { + recorder.stop(); + recorder = null; + } + + isRecording = false; + Utils.scanFile(curVideoPath, getContext()); + } } diff --git a/app/src/main/java/com/simplemobiletools/camera/Utils.java b/app/src/main/java/com/simplemobiletools/camera/Utils.java index a8e34252..5a77d25f 100644 --- a/app/src/main/java/com/simplemobiletools/camera/Utils.java +++ b/app/src/main/java/com/simplemobiletools/camera/Utils.java @@ -1,10 +1,17 @@ package com.simplemobiletools.camera; import android.content.Context; +import android.content.res.Resources; import android.hardware.Camera; +import android.media.MediaScannerConnection; +import android.os.Environment; import android.widget.Toast; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.List; +import java.util.Locale; public class Utils { public static Camera.CameraInfo getCameraInfo(int cameraId) { @@ -36,4 +43,38 @@ public class Utils { return true; } + + public static String getOutputMediaFile(Context context, boolean isPhoto) { + final File mediaStorageDir = getFolderName(context, isPhoto); + + if (!mediaStorageDir.exists()) { + if (!mediaStorageDir.mkdirs()) { + return ""; + } + } + + final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); + if (isPhoto) { + return mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"; + } else { + return mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4"; + } + } + + private static File getFolderName(Context context, boolean isPhoto) { + final Resources res = context.getResources(); + final String appName = res.getString(R.string.app_name); + final String sharedPath = new File(Environment.getExternalStorageDirectory(), appName).getAbsolutePath(); + String typeDirectory = res.getString(R.string.photo_directory); + if (!isPhoto) { + typeDirectory = res.getString(R.string.video_directory); + } + + return new File(sharedPath, typeDirectory); + } + + public static void scanFile(String path, Context context) { + final String[] paths = {path}; + MediaScannerConnection.scanFile(context, paths, null, null); + } } diff --git a/app/src/main/res/mipmap-hdpi/video_stop.png b/app/src/main/res/mipmap-hdpi/video_stop.png new file mode 100644 index 0000000000000000000000000000000000000000..72847bb3ae3942b422878a7b9498e59b354187f9 GIT binary patch literal 1574 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 M07*qoM6N<$g4kZTj{pDw literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/video_stop.png b/app/src/main/res/mipmap-xxhdpi/video_stop.png new file mode 100644 index 0000000000000000000000000000000000000000..c6896893d01e4f94dbb5bc67ecd72bc67bfdc7d9 GIT binary patch literal 3944 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 M$ilGZKkiZg1@hq(^#A|> literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d416ca48..025402ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,9 @@ Simple Camera An error occurred at obtaining the camera + An error occurred at creating the video file + Simple Videos + Simple Photos About