录制会在某些设备上生成有效的mp4文件,但会在我正在使用的设备上生成损坏的mp4文件。这个受损文件的特点是绿色,每个看到它的人都评论说它看起来像编解码器问题。即使在录制过程中,您也可以看到当该帧消失并显示下一帧时,当前帧中的某些对象不会被删除。
public class Record_activity extends ActionBarActivity {
RecordFragment m_recordFragment=new RecordFragment(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_activity);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container,m_recordFragment ).commit();
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
m_recordFragment.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.record_activity, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class RecordFragment extends Fragment {
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static Camera mCamera;
private CameraPreview mPreview;
Context m_context;
private MediaRecorder mMediaRecorder;
private boolean isRecording = false;
private Button m_captureButton;
private int ScreenWidth;
private int ScreenHeight;
public RecordFragment(Context aContext) {
m_context=aContext;
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(boolean aIsBackCamera){
if(mCamera==null)
{
int numCameras=Camera.getNumberOfCameras();
try {
if(aIsBackCamera)
mCamera = Camera.open(0); // attempt to get a Camera instance
else mCamera=Camera.open(numCameras-1); // attempt to get a Camera instance
}
catch (Exception e){
Log.d("record", "open camera exception:"+e.getMessage());
// Camera is not available (in use or does not exist)
}
}
return mCamera; // returns null if camera is unavailable
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_record_activity,
container, false);
// Create an instance of Camera
mCamera = getCameraInstance(true);
Display display =((Activity)m_context).getWindowManager().getDefaultDisplay();
ScreenWidth = display.getWidth(); // deprecated
ScreenHeight = display.getHeight(); // deprecated
Log.d("record", "screenWidth:"+ScreenWidth+"screenHeight:"+ScreenHeight);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(m_context, mCamera);
FrameLayout preview = (FrameLayout) rootView.findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
m_captureButton = (Button) rootView.findViewById(R.id.button_capture);
m_captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
setCaptureButtonText("Capture");
isRecording = false;
} else {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
setCaptureButtonText("Stop");
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
private void setCaptureButtonText(String string) {
m_captureButton.setText(string);
}
}
);
return rootView;
}
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance(true);
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("record", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d("record", "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
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;
}
}
/** 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), "MyCameraApp");
// 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("MyCameraApp", "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;
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera = getCameraInstance(true);
mCamera.setPreviewDisplay(holder);
// mCamera.startPreview();
} catch (IOException e) {
Log.d("record", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
}
else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
// mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
Parameters params=mCamera.getParameters();
Size size=getBestPreviewSize(w, h,params );
Log.d("record", "surface width:"+w+"surface height"+h+"previewWidth:"+size.width+"previewHeight:"+size.height);
params.setPreviewSize(size.width,size.height);
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
// set preview size and make any resize, rotate or
// reformatting changes here
mCamera.startPreview();
} catch (Exception e){
Log.d("record", "Error starting camera preview: " + e.getMessage());
}
}
}
}
/** A basic Camera preview class */
}
fragment_record_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.recordapp.RecordFragment" >
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Capture" />
</LinearLayout>
答案 0 :(得分:0)
O.K,我找到了答案,我使用了http://developer.android.com/samples/MediaRecorder/index.html,它有编解码器支持,问题解决了。