2013-02-24 106 views
20

我尝试在Android 4.0中组织背景视频录制。但我不能这样做,因为这些问题:Android 4.0中的背景视频录制

  1. 虚假表面在MediaRecorder(错误:无效的面)不工作

  2. 如果您使用的表面活性1×1像素,表面被破坏的活动暂停(停止记录)

  3. 如果您在使用WindowsManager表面1×1像素,表面被破坏的应用程序暂停(停止记录)

  4. 面传热eTexture不MediaRecorder.setPreviewDisplay(新的表面(表面纹理))工作

  5. 的Widget不允许处理表面1×1像素

  6. 状态栏不允许处理表面1×1像素

请帮助我找到正确的方法。

+1

你可以给我的代码隐藏的摄像头 – 2015-12-16 07:27:31

回答

-4

我找到了答案:有必要使用WindowManager并从Service中调用它。

+6

请ü可以发布您的代码 – 2013-03-04 08:27:42

+1

ü可以发布您的代码.... – 2013-04-09 11:24:04

+1

请ü可以发布您的代码 – 2015-07-08 15:38:45

39

样品和简单的代码(在果冻豆,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; } 

} 

不要忘记权限:

<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

即将发布。诀窍是将MediaRecorder设置在OnSurfaceCreated上,之后它变得非常简单。 – 2013-06-03 16:32:01

+0

谢谢你提供了很棒的代码,但我遇到了一个小问题。我在Nexus 5X上测试过它,并且相机颠倒了。我尝试了camera.setDisplayOrientation(90)和camera.getParameters()。setRotation(90),但没有任何更改摄像机的方向。你有什么想法如何改变它? – Michal 2016-12-21 21:15:32

+0

我真的很抱歉回答这么晚。我希望这有助于:https://plus.google.com/+AndroidDevelopers/posts/jXNFNKWxsc3 - 如果没有,你可以试试这个:mediaRecorder.setOrientationHint(180); - 它不会改变相机的方向,但会告诉视频播放器在播放时改变方向。这是我所知道的一切。 – cman 2017-04-02 18:01:42

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

只是一个小的修改上面的代码。 ..它会将5秒的文件保存到你的SD卡的根文件夹...根据你的需要修改定时器。和它的工作在Nexus 4和福邦以及..