2011-06-17 19 views
7

मैं एंड्रॉइड डेवलपमेंट (एसडीके 2.2) का उपयोग कर रहा हूं और मैं mediaRecorder के साथ एक वीडियो रिकॉर्डिंग करना चाहता हूं और साथ ही, प्रत्येक पूर्वावलोकन फ्रेम पर कुछ प्रक्रिया करता हूं।वीडियो रिकॉर्डिंग के दौरान एंड्रॉइड पूर्वावलोकन प्रसंस्करण

मैं रिकॉर्ड एक परियोजना में MediaRecorder के साथ वीडियो, एक अन्य में मैं पूर्वावलोकन चित्रों के प्रसंस्करण के लिए onPreviewFrame(byte[] data, Camera camera) (PreviewCallback से) का उपयोग करें।

मैंने कैमरा बनाने और mediaRecorder (setCamera फ़ंक्शन) के साथ इसका उपयोग करने का प्रयास किया है, लेकिन यह काम नहीं करता है।

क्या यह दोनों एक ही समय में करना संभव है?

असल में मुझे समझ में नहीं आता कि दो चीजों को कैसे लिंक किया जाए?

मेरे कोड:

package ch.fraise; 

import java.io.IOException; 
import android.app.Activity; 
import android.hardware.Camera; 
import android.hardware.Camera.PreviewCallback; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class CameraActivity extends Activity implements SurfaceHolder.Callback, 
    Camera.AutoFocusCallback { 

private SurfaceView preview; 
private SurfaceHolder previewHolder; 

private MediaRecorder mRecorder; 
private Camera mCamera; 
private boolean mPreviewRunning = false; 
private boolean mCaptureFrame = false; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.e("", "Begin onCreate"); 
    setContentView(R.layout.main); 

    preview = (SurfaceView) findViewById(R.id.surfaceView1); 
    previewHolder = preview.getHolder(); 
    previewHolder.addCallback(this); 
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    mRecorder = new MediaRecorder(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    MenuInflater inflater = getMenuInflater(); 
    inflater.inflate(R.menu.capture_menu, menu); 
    return true; 
} 

public void startRecording() { 
    Log.e("", "Begin StartRecording"); 
    mCaptureFrame = true; 
    mRecorder.start(); 
} 

public void stopRecording() { 
    Log.e("", "Begin StopChange"); 
    mRecorder.stop(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle item selection 
    switch (item.getItemId()) { 
    case R.id.startRecording: 
     startRecording(); 
     return true; 
    case R.id.stopRecording: 
     stopRecording(); 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Log.e("", "Begin surfaceDestroy"); 
    mCamera = Camera.open(); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mCamera.stopPreview(); 
    mPreviewRunning = false; 
    mCamera.release(); 

    mRecorder.reset(); 
    mRecorder.release(); 
} 

@Override 
public void onAutoFocus(boolean success, Camera camera) { 
    // TODO Auto-generated method stub 

} 

/* 
* PreviewCallback() 
* 
* this callback captures the preview at every frame and puts it in a byte 
* buffer. we will evaluate if this is a frame that we want to process, and 
* if so, we will send it to an asynchronous thread that will process it to 
* an ARGB Bitmap and POST it to the server 
*/ 
PreviewCallback previewCallback = new PreviewCallback() { 
    public void onPreviewFrame(byte[] data, Camera camera) { 
     Log.e("", "onPreviewFrame pass"); 
     if (mCaptureFrame) { 
      mCaptureFrame = false; 
      // new FrameHandler().execute(data); 
     } 
    } 
}; 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    Log.e("", "Begin SurfaceChange"); 

    mRecorder.reset(); 
    mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
    mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); 
    mRecorder.setOutputFile("/sdcard/videotest2.mp4"); 
    mRecorder.setVideoFrameRate(30); 

    mRecorder.setPreviewDisplay(previewHolder.getSurface()); 
    try { 
     mRecorder.prepare(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    if (mPreviewRunning) 
     mCamera.stopPreview(); 

    Camera.Parameters p = mCamera.getParameters(); 
    // p.setPreviewSize(width, height); 
    mCamera.setParameters(p); 

    try { 
     mCamera.setPreviewDisplay(holder); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    mCamera.setPreviewCallback(previewCallback); 

    mCamera.startPreview(); 
    mPreviewRunning = true; 

} 

} 

और एक्सएमएल फ़ाइल में अनुमतियाँ:

<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
<uses-permission android:name="android.permission.RECORD_VIDEO" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
+0

आपका प्रश्न क्या है:

उदाहरण के लिए

? – YXD

+0

मैंने अपना कोड जोड़ा है लेकिन मेरे पास निम्न त्रुटि है W/System.err (5476): java.io.IOException: तैयार विफल। जब तक मैं वीडियो रिकॉर्डिंग शुरू नहीं करता, तब तक इस पहली त्रुटि के बाद एप्लिकेशन चलाया जाता है। तब मेरे पास java.lang.IleglegalStateException ई/एंड्रॉइड रनटाइम (5476): android.media.MediaRecorder.start (मूल विधि) –

उत्तर

0

आप बस अपनी मैनिफ़ेस्ट फ़ाइल इस प्रकार यह नीचे दिया गया कोड work.Sample जाएगा टैग को जोड़ने।

जैसे: -

</application> 
    <uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
<uses-permission android:name="android.permission.RECORD_VIDEO" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    ***<uses-feature android:name="android.hardware.camera" />*** 
</manifest> 
+0

हाय निखिलकिलीवायिल! आपकी सहायताके लिए धन्यवाद! दुर्भाग्यवश मैंने लाइन <उपयोग-सुविधा एंड्रॉइड: नाम = "android.hardware.camera" /> जोड़ा है लेकिन ऐसा लगता है कि यह या तो काम नहीं कर रहा है। मैंने देखा है कि रिकॉर्डिंग शुरू होने पर, ऑनफ्रेम पूर्वावलोकन कहलाता है! शायद वे एक साथ भाग सकते हैं !? –

+0

मुझे एक ही समस्या है। अगर आपको जवाब मिल गया तो कृपया मुझे सूचित करें .. – nikhilkilivayil

+0

मुझे यह समस्या भी है। क्या हम कच्चे चित्र को वास्तविक समय प्राप्त करने के लिए वीडियो को डीकोड करने का प्रयास कर सकते हैं? –

4

आप वीडियो स्ट्रीम रिकॉर्डिंग के दौरान, onPreviewFrame बुलाया नहीं किया जाएगा एक बार आप रिकॉर्डिंग शुरू तक नहीं पहुँच सकता। अजीब तरह, onPreviewFrame के बाद आप या तो रिकॉर्ड ... कहा जाता है करने के लिए प्रतीत नहीं होता

+1

यह गलत है। रिकॉर्डिंग के बाद आपको बस फिर से सुनना शुरू करना होगा। –

0

यदि आप ओएस 2.2 या उच्चतर का उपयोग कर रहे तो इस विधि का उपयोग अपने तैयार में विफल रहा है और अन्य अपवाद

public boolean startRecording() { 
    try { 
     camera.unlock(); 

     mediaRecorder = new MediaRecorder(); 
     mediaRecorder.setCamera(camera); 
     mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
     mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
     mediaRecorder.setProfile(CamcorderProfile 
       .get(CamcorderProfile.QUALITY_HIGH)); 

     File tempFile = new File(getOutputMediaFile(MEDIA_TYPE_VIDEO) 
       .toString()); 

     mediaRecorder.setOutputFile(tempFile.getPath()); 
     mediaRecorder.setVideoFrameRate(videoFramesPerSecond); 
     mediaRecorder.setVideoSize(surfaceView.getWidth(), 
       surfaceView.getHeight()); 
     mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 
     mediaRecorder.setMaxFileSize(maxFileSizeInBytes); 
     mediaRecorder.prepare(); 
     mediaRecorder.start(); 

     return true; 
    } catch (IllegalStateException e) { 
     Log.e(TAG, e.getMessage()); 
     e.printStackTrace(); 
     return false; 
    } catch (IOException e) { 
     Log.e(TAG, e.getMessage()); 
     e.printStackTrace(); 
     return false; 
    } 
} 
6

यूरेका हटा दिया जाएगा! चाल SurfaceHolder.Callback में अपने PreviewCallback को संलग्न करना है! ऐसा करने के बाद, MediaRecorder चलने के बाद आपको पूर्वावलोकन फ्रेम डेटा प्राप्त करना जारी रहेगा!

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    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)); 
      } 
     }); 

} 
+1

मैं इसे ऊपर की तरह करता हूं, लेकिन MediaRecorder चलने के बाद भी पूर्वावलोकन फ्रेम डेटा नहीं मिल सकता है! यह वास्तव में आपके लिए काम करता है? – whutdyp

+0

हाँ, मैं उस समय एंड्रॉइड 4.2 का उपयोग कर रहा था। सुनिश्चित करें कि आप SufaceHolder संलग्न करते हैं।MediaRecorder शुरू करने से पहले कॉलबैक। अपना स्रोत पोस्ट करें और मैं एक नज़र डालेगा। – dbro

+0

@ डीब्रो, नहीं। आपकी चाल काम नहीं करती है। अगर मैं 'mMediaRecorder.setCamera (mCamera)' विधि को कॉल करता हूं, तो मुझे पूर्वावलोकन फ्रेम प्राप्त करने से पहले 'mCamera.unlock()' को कॉल करना होगा। अगर मैं 'mMediaRecorder.setCamera (mCamera) 'विधि,' mMediaRecorder.start()' 'IllegalStateException' के साथ क्रैश नहीं करता हूं क्योंकि कैमरा पहले से उपयोग में है। क्या आप अधिक (या पूर्ण) कोड पोस्ट कर सकते हैं आपने अपनी यूरेका चाल कैसे की? –

संबंधित मुद्दे