Grabación de vídeo de fondo en Android 4.0
Trato de organizar la grabación de vídeo de fondo en Android 4.0. Pero no puedo hacerlo debido a estos problemas:
-
Dummy Surface no funciona en MediaRecorder (error: superficie no válida)
-
Si utiliza Superficie 1 x 1 px en Actividad, Superficie se destruye en Pausa de actividad (la grabación se detiene)
-
Si utiliza Surface 1 x 1 px en WindowsManager, Superficie se destruye en Pausa de aplicación (se detiene la grabación)
-
SurfaceTexture no funciona en MediaRecorder.setPreviewDisplay (new Surface (SurfaceTexture))
-
Widget no permite manejar Surface 1 x 1 px
-
La barra de estado no permite manejar Superficie 1 x 1 px
Por favor, ayúdame a encontrar el camino correcto.
- Vídeo de Android reiniciado con orientación
- Cómo reproducir vídeos en android desde la carpeta de activos o la carpeta en bruto?
- ¿Por qué el tamaño de la vista de video cambió automáticamente dependiendo del tamaño del video?
- Android: Vista de vídeo: cómo reproducir un video en un bucle
- Crear video desde imágenes
- Reproducción automática de vídeos (vista de lista)
- Pantalla negra al volver a la actividad de reproducción de vídeo en Android
- Estiramiento para rellenar VideoView, relación de aspecto de VideoView
Muestra y código simple (probado en Jelly Bean, SGS2):
public class BackgroundVideoRecorder extends Service implements SurfaceHolder.Callback { private WindowManager windowManager; private SurfaceView surfaceView; private Camera camera = null; private MediaRecorder mediaRecorder = null; @Override public void onCreate() { // Start foreground service to avoid unexpected kill Notification notification = new Notification.Builder(this) .setContentTitle("Background Video Recorder") .setContentText("") .setSmallIcon(R.drawable.ic_launcher) .build(); startForeground(1234, notification); // 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); 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); } // Method called right after Surface created (initializing and starting MediaRecorder) @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { camera = Camera.open(); 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_HIGH)); mediaRecorder.setOutputFile( Environment.getExternalStorageDirectory()+"/"+ DateFormat.format("yyyy-MM-dd_kk-mm-ss", new Date().getTime())+ ".mp4" ); try { mediaRecorder.prepare(); } catch (Exception e) {} mediaRecorder.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; } }
No olvide los permisos:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
try { mediaRecorder.prepare(); } catch (Exception e) {} mediaRecorder.start(); Timer t = new Timer(); t.schedule(new TimerTask() { @Override public void run() { stopSelf(); } }, 5000); }catch(Exception e){}
Sólo una pequeña modificación al código anterior … se guardará el archivo 5sec a la carpeta raíz en ur sdcard … modificar el temporizador de acuerdo a la necesidad ur. Y trabajó en Nexus 4 y Micromax también.
He encontrado la respuesta: es necesario usar WindowManager y llamar desde el servicio.
- Android edittext en listview pierde el foco en llamar notificydatachanged
- ¿Cómo puedo compartir un archivo SharedPreferences a través de dos aplicaciones de Android diferentes?