2013-02-24 32 views
20

Próbuję zorganizować nagrywanie wideo w tle w systemie Android 4.0. Ale nie mogę tego zrobić z powodu tych problemów:Nagrywanie wideo w tle w systemie Android 4.0

  1. Dummy Surface nie działa w MediaRecorder (błąd: nieprawidłowa powierzchni)

  2. Jeśli używasz powierzchni 1 x 1 px działalności, Surface jest zniszczona na pauzie Aktywny (nagrywanie jest zatrzymane)

  3. Jeśli używasz powierzchni 1 x 1 px na WindowsManager, nawierzchnia jest zniszczona na pauzie Application (nagrywanie jest zatrzymane)

  4. powierzch eTexture nie działa w MediaRecorder.setPreviewDisplay (nowa nawierzchnia (SurfaceTexture))

  5. Widżet nie pozwala obsłużyć powierzchnia 1 x 1 px

  6. Pasek stanu nie pozwala obsłużyć powierzchnia 1 x 1 px

Proszę, pomóż mi znaleźć właściwą drogę.

+1

możesz dać mi kod ukrytej kamery –

Odpowiedz

-4

Znalazłem odpowiedź: konieczne jest użycie WindowManager i wywołanie go z Serwisu.

+6

pls u można pisać kod –

+1

u można pisać kod .... –

+1

pls u można pisać kod –

39

próbki i prosty kod (testowane na 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; } 

} 

Nie zapomnij o uprawnieniach:

<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" /> 
+0

Zamierzasz to opublikować. Sztuką jest ustawienie MediaRecorder na OnSurfaceCreated, po czym staje się całkiem proste. –

+0

Dziękuję za świetny kawałek kodu, ale mam z tym mały problem. Przetestowałem to na Nexusie 5X i uzyskałem dodatkową kamerę. Próbowałem camera.setDisplayOrientation (90) i camera.getParameters(). SetRotation (90), ale nic nie zmienia orientacji kamery. Czy masz pojęcie, jak to zmienić? – Michal

+0

Naprawdę przepraszam za odpowiedź tak późno. Mam nadzieję, że to pomoże: https://plus.google.com/+AndroidDevelopers/posts/jXNFNKWxsc3 - jeśli nie, spróbuj tego: mediaRecorder.setOrientationHint (180); - nie zmienia orientacji kamery, ale informuje odtwarzacz wideo o zmianie orientacji podczas grania. To wszystko co wiem. – cman

2
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){} 

Wystarczy niewielka modyfikacja powyższego kodu. ... to zapisze plik 5sec w folderze głównym w ur sdcard ... zmodyfikuj timer zgodnie z potrzebą. i to działa na Nexusie 4 i Micromax jak dobrze ..

Powiązane problemy