package com.example.rotorm; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.PutObjectRequest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.PreviewCallback; import android.media.AudioManager; import android.media.CamcorderProfile; import android.media.MediaPlayer; import android.media.MediaRecorder; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.SurfaceHolder; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.FrameLayout; public class CameraActivity extends Activity implements SurfaceHolder.Callback, OnClickListener { private static final String TAG = "CameraRecorderActivity"; public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; private Camera mCamera; private Preview mPreview; private MediaRecorder mMediaRecorder; private Button captureButton; private boolean isRecording = false; private MediaPlayer mp; private String filename=""; private String audiofilename; private Uri audioUri; private boolean intentStarted=false; private static final String AWS_S3_BUCKET_NAME="rotor-development"; private static final String AWS_S3_BUCKET_ENDPOINT="s3-eu-west-1.amazonaws.com"; private static final String AWS_ACCESS_KEY_ID="AKIAIXPDDG4VNFOWMXHQ"; private static final String AWS_SECRET_KEY="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"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Intent intent = new Intent(); //intent.setAction(android.content.Intent.ACTION_PICK); //intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); //startActivityForResult(intent, 1234); //0 stops picker if (!intentStarted){ //dirty hack, without this it does the intent twice for some reason? intentStarted=true; Intent intent = new Intent(); intent.setType("audio/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent,1); } //why does this get intent twice? //and crash 2nd time? //final Uri uri=Uri.parse(Environment.getExternalStorageDirectory()+"/Audio/abc.mp3"); } public void mCallback() { } public void onActivityResult(int requestCode, int resultCode, Intent data){ if(resultCode != RESULT_OK){ Log.i("could not pick audio","ERROR"); return; } audioUri = data.getData(); audiofilename=audioUri.toString(); Log.i("returned data from intent: "+audiofilename, "SUCCESS"); // Create an instance of Camera. mCamera = getCameraInstance(); // Create preview view and set it as the content of our activity. mPreview = new Preview(this, mCamera); //int i = R.id.preview; //Object o = this.findViewById(i); //FrameLayout preview = (FrameLayout) o; //preview.addView(mPreview); mPreview.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); ((FrameLayout) findViewById(R.id.preview)).addView(mPreview); mPreview.setKeepScreenOn(true); // Add a listener to the Capture button captureButton = (Button) findViewById(R.id.buttonClick); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (isRecording) { mp.stop(); // stop recording and release camera mMediaRecorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object mCamera.lock(); // take camera access back from MediaRecorder Log.i("recorded "+filename, "END"); // inform the user that recording has stopped setCaptureButtonText("Capture"); isRecording = false; //we are now ready to upload the file //http://aws.amazon.com/articles/SDKs/Android/3002109349624271 AmazonS3Client s3Client = new AmazonS3Client( new BasicAWSCredentials( AWS_ACCESS_KEY_ID, AWS_SECRET_KEY ) ); //our bucket already exists //PutObjectRequest por = new PutObjectRequest( Constants.getPictureBucket(), Constants.PICTURE_NAME, new java.io.File( filePath) ); //s3Client.putObject( por ); } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording //prepare to play audio try { mp = MediaPlayer.create(getApplicationContext(),audioUri); //mp.setDataSource(audiofilename); //mp.prepare(); mp.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } //catch (IOException e) { // e.printStackTrace(); //} Log.i("starting to record", "BEGIN"); mMediaRecorder.start(); // inform the user that recording has started setCaptureButtonText("Stop"); isRecording = true; } else { // prepare didn't work, release the camera releaseMediaRecorder(); // inform user } } } } ); } public void setCaptureButtonText(String s) { captureButton.setText(s); } @Override public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, now tell the camera where to draw the preview. try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "RotorM"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("RotorM", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; } private boolean prepareVideoRecorder(){ //mCamera = getCameraInstance(); mMediaRecorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder mCamera.unlock(); mMediaRecorder.setCamera(mCamera); // Step 2: Set sources //and there is no option to set a NULL audio source //mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //if you don't use a profile how to raise quality? //121113 if you don't set audio source re //11-12 11:56:19.893: E/MediaRecorder(6637): try to set the audio encoder without setting the audio source first mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //without this capture doesn't begin mMediaRecorder.setVideoSize(1280,720); mMediaRecorder.setVideoFrameRate(25); mMediaRecorder.setVideoEncodingBitRate(3000000); //so the combination of these 3 things does work //11-12 11:25:06.138: E/AndroidRuntime(5094): java.lang.RuntimeException: getParameters failed (empty parameters) //Camera.Parameters params = mCamera.getParameters(); //how to get parameters? //List sizes=params.getSupportedVideoSizes(); //params.setPictureSize(1280, 720); //mCamera.setParameters(params); //how to manually set profile????? //List sizes = mCamera.getSupportedVideoSizes(); //mCamera.setSize(720,480); //mMediaRecorder.setVideoSize(720, 480); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) //11-12 11:58:28.628: E/AndroidRuntime(6884): java.lang.IllegalArgumentException: Number of channels is not positive //mMediaRecorder.setAudioChannels(0); //11-12 11:26:24.213: E/MediaRecorder(5226): setOutputFormat called in an invalid state: 4 //mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // Step 4: Set output file filename=getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(); //temporary mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); //mCamera.setPreviewCallback(new PreviewCallback() { // public void onPreviewFrame(byte[] _data, Camera _camera) { // Log.d("onPreviewFrame-surfaceChanged",String.format("Got %d bytes of camera data", _data.length)); // } //}); // Step 6: Prepare configured MediaRecorder try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; } private void getSupportedVideoSizes() { // TODO Auto-generated method stub } @Override public void onClick(View v) { Log.i("onClick", "BEGIN"); //if(!recording) { // recording = startRecording(); //} else { // stopRecording(); // recording = false; //} //Log.i("onClick", "END"); } @Override protected void onPause() { super.onPause(); releaseMediaRecorder(); // if you are using MediaRecorder, release it first releaseCamera(); // release the camera immediately on pause event } private void releaseMediaRecorder(){ if (mMediaRecorder != null) { mMediaRecorder.reset(); // clear recorder configuration mMediaRecorder.release(); // release the recorder object mMediaRecorder = null; mCamera.lock(); // lock camera for later use } } private void releaseCamera(){ if (mCamera != null){ mCamera.release(); // release the camera for other applications mCamera = null; } } private Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance //c = this.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } public Camera open() { int numberOfCameras = Camera.getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numberOfCameras; i++) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { return Camera.open(i); } } return null; } }