मैंने पृष्ठभूमि में सामने वाले कैमरे को रिकॉर्ड करने के लिए नीचे दिखाए गए एंड्रॉइड सेवा को लिखा है। यह बहुत अच्छी तरह से काम करता है। लेकिन अब मैं रिकॉर्डिंग करते समय हर 5 सेकंड में एक तस्वीर लेना चाहता हूं। क्या यह किसी भी तरह से संभव है? जब मैं दूसरा कैमरा खोलने की कोशिश करता हूं (दूसरी सेवा में) मुझे एक त्रुटि मिल रही है।एंड्रॉइड पर वीडियो रिकॉर्ड करते समय तस्वीर लेना
public class RecorderService extends Service implements SurfaceHolder.Callback {
private WindowManager windowManager;
private SurfaceView surfaceView;
private Camera camera = null;
private MediaRecorder mediaRecorder = null;
@Override
public void onCreate() {
// Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
surfaceView = new SurfaceView(this);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
1, 1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
windowManager.addView(surfaceView, layoutParams);
surfaceView.getHolder().addCallback(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
//.setSmallIcon(R.mipmap.app_icon)
.setContentTitle("Background Video Recorder")
.setContentText("")
.setContentIntent(pendingIntent).build();
startForeground(MainActivity.NOTIFICATION_ID_RECORDER_SERVICE, notification);
return Service.START_NOT_STICKY;
}
// Method called right after Surface created (initializing and starting MediaRecorder)
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
camera = Camera.open(1);
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
FileUtil.createDir("/storage/emulated/0/Study/Camera");
mediaRecorder.setOutputFile("/storage/emulated/0/Study/Camera/" + Long.toString(System.currentTimeMillis()) + ".mp4");
try { mediaRecorder.prepare(); } catch (Exception e) {}
mediaRecorder.start();
try {
camera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
Runnable runnable = new PictureThread(camera);
Thread thread = new Thread(runnable);
thread.start();
}
// Stop recording and remove SurfaceView
@Override
public void onDestroy() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
camera.lock();
camera.release();
windowManager.removeView(surfaceView);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {}
@Override
public IBinder onBind(Intent intent) { return null; }
}
संपादित: मैं अब एक धागा PictureThread
लिखा है। यह धागा RecorderService
से शुरू हुआ है और वीडियो रिकॉर्डिंग के दौरान एक तस्वीर लेने की कोशिश करता है।
public class PictureThread implements Runnable {
private final static String TAG = PictureThread.class.getSimpleName();
private Camera camera;
PictureThread(Camera camera) {
this.camera = camera;
}
@Override
public void run() {
camera.startPreview();
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
}
};
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "onPictureTaken - jpeg");
}
};
}
दुर्भाग्य jpegCallback
कभी नहीं कहा जाता हो जाता है (अर्थात लॉग संदेश मुद्रित कभी नहीं है)। जब मैं अपने टैबलेट का कैमरा ऐप खोलता हूं तो मैं वीडियो रिकॉर्डिंग के दौरान चित्र ले सकता हूं, इसलिए यह संभव होना चाहिए।
मैंने एलेक्स कोह्न (https://github.com/mobapptuts/android_camera2_api_video_app) द्वारा सुझाए गए कैमरे 2 एपीआई उदाहरण की भी कोशिश की है। एक वीडियो काम रिकॉर्ड करना और एक तस्वीर भी लेना काम करता है लेकिन जब मैं रिकॉर्डिंग करते समय एक तस्वीर लेने की कोशिश करता हूं, तो कोई चित्र नहीं बनाया जाता है (लेकिन कोई त्रुटि नहीं)। फिर भी, मुझे यह उदाहरण ऐप बहुत विश्वसनीय काम नहीं कर रहा है (शायद एक और उदाहरण ऐप है)।
संपादित 2: shutterCallback
और takePicture
की rawCallback
कहा जाता हो जाता है लेकिन rawCallback
का डेटा रिक्त है। jpegCallback
कभी नहीं बुलाया जाता है .. कोई विचार क्यों और कैसे हल किया जा सकता है? मैंने बुलाए जाने के लिए कॉलबैक समय देने के लिए थोड़े समय के लिए थ्रेड में इंतजार करने की भी कोशिश की है और मैंने अपनी मुख्य गतिविधि में कॉलबैक को स्थिर करने की कोशिश की है (ताकि यह कचरा एकत्र न हो)। कुछ भी काम नहीं किया।
कच्चे कॉलबैक पर डेटा रिकॉर्डिंग के बिना भी शून्य है। पिछले 10 वर्षों में मुझे एक डिवाइस नहीं मिला जो इस कॉलबैक पर सार्थक डेटा प्रदान करता था। जेपीजी कॉलबैक के लिए, आपको क्या विश्वास है कि इसे काम करना चाहिए? –
@AlexCohn jpegCallback क्यों काम नहीं करना चाहिए? मुझसे कोई गलती हो गई क्य? एंड्रॉइड स्टॉक कैमरा ऐप के साथ मैं रिकॉर्डिंग करते समय चित्र ले सकता हूं इसलिए मुझे विश्वास है कि इसे काम करना चाहिए ... – machinery
वह डिवाइस कौन सा है? –