capture video in background
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MainActivity.java
1 package ai.suanzi.rtmpclient;
2
3 import android.graphics.ImageFormat;
4 import android.graphics.SurfaceTexture;
5 import android.support.v7.app.AppCompatActivity;
6 import android.os.Bundle;
7 import android.util.Log;
8 import android.view.SurfaceHolder;
9 import android.hardware.Camera;
10 import android.view.SurfaceView;
11 import android.view.View;
12 import android.widget.Button;
13 import android.widget.Toast;
14 import android.content.Context;
15 import android.content.pm.PackageManager;
16 import android.os.AsyncTask;
17 import java.util.List;
18 import java.io.IOException;
19 import java.util.concurrent.ExecutorService;
20 import java.util.concurrent.Executors;
21
22
23
24 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{
25
26     private static final String TAG = "PENG";
27     private Ffmpeg ffmpeg = new Ffmpeg();
28     private Camera mCamera ;//= getCameraInstance();
29     private StreamTask mStreamTask;
30     private SurfaceHolder mHolder;
31     ExecutorService mExecutor = Executors.newSingleThreadExecutor();
32
33     @Override
34     protected void onCreate(Bundle savedInstanceState) {
35         super.onCreate(savedInstanceState);
36         setContentView(R.layout.activity_main);
37         Log.e(TAG, "Ffmpeg Version: " + ffmpeg.getVersion());
38
39         final Button btn = findViewById(R.id.button);
40         btn.setText("Start");
41         btn.setOnClickListener(new View.OnClickListener() {
42             @Override
43             public void onClick(View v) {
44                 Log.e(TAG, "Button " + btn.getText() + " onClick");
45                 if (mCamera == null) return;
46                 if(btn.getText().equals("Start")){
47                     mCamera.startPreview();
48                     Camera.Parameters params = mCamera.getParameters();
49                     //params.setPreviewFpsRange(30000, 30000);
50                     //params.setPictureSize(320, 240);
51                     //params.setPictureFormat(ImageFormat.NV21);
52                     //mCamera.setParameters(params);
53
54
55
56
57                     ffmpeg.init(params.getPictureSize().width, params.getPictureSize().height);
58                 } else {
59                     mCamera.setPreviewCallback(null);
60                     Toast.makeText(MainActivity.this, "encode done", Toast.LENGTH_SHORT).show();
61                     ffmpeg.flush();
62                     ffmpeg.close();
63                 }
64                 btn.setText(btn.getText().equals("Start") ? "Stop" : "Start");
65             }
66         });
67
68         this.mCamera = getCameraInstance();
69         if(checkCameraHardware(this)) Log.e(TAG, "has cameras: " + Camera.getNumberOfCameras());
70
71         final SurfaceView surfaceView = findViewById(R.id.surfaceView);
72         mHolder = surfaceView.getHolder();
73         mHolder.addCallback(this);
74
75         //
76         mCamera.setPreviewCallback(this);
77
78         /*try{
79             mCamera.setPreviewTexture(st);
80         }catch (IOException e){
81             e.printStackTrace();
82         }*/
83
84     }
85
86     SurfaceTexture st = new SurfaceTexture(0);
87
88
89     @Override
90     protected void onPause(){
91         super.onPause();
92         Log.e(TAG, "OnPause");
93         //ffmpeg.flush();
94         //ffmpeg.close();
95     }
96
97     @Override
98     protected void onResume() {
99         super.onResume();
100         Log.e(TAG, "OnResume");
101     }
102
103     @Override
104     protected void onStop() {
105         super.onStop();
106         Log.e(TAG,"onStop");
107     }
108
109     @Override
110     protected void onStart(){
111         super.onStart();
112         Log.e(TAG,"onStart");
113     }
114
115     @Override
116     protected void onDestroy(){
117         super.onDestroy();
118         Log.e(TAG,"onDestroy");
119     }
120
121     @Override
122     protected void onRestart(){
123         super.onStart();
124         Log.e(TAG,"onRestart");
125     }
126
127     // class StreamTask AsyncTask
128     private class StreamTask extends AsyncTask<Void, Void, Void>{
129         private byte[] data;
130
131         StreamTask(byte[] data){
132             this.data = data;
133         }
134
135         @Override
136         protected Void doInBackground(Void... params) {
137
138             if (this.data != null){
139                 Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate());
140                 ffmpeg.process(this.data);
141             }
142             return null;
143         }
144     }
145
146     // SurfaceHolder.Callback implementation
147     @Override
148     public void surfaceCreated(final SurfaceHolder holder){
149         Log.e(TAG,"SurfacedCreated");
150         try {
151             mCamera.setPreviewDisplay(holder);
152             //mCamera.startPreview();
153         } catch (IOException e) {
154             Log.d(TAG, "Error setting camera preview: " + e.getMessage());
155         }
156     }
157
158     @Override
159     public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
160         Log.e(TAG, "surfaceChanged");
161         //if(mCamera==null) return;
162         //Camera.Parameters parameters=mCamera.getParameters();
163         //parameters.setPreviewSize(640,480);
164         //parameters.setPictureSize(640,480);
165         //mCamera.setParameters(parameters);
166     }
167
168     @Override
169     public void surfaceDestroyed(SurfaceHolder holder){
170         Log.e(TAG, "surfaceDestroyed");
171     }
172
173     private long encodeCount = 0;
174     private long count = 0;
175     private long previewTime;
176     // Camera.PreviewCallback
177     @Override
178     public void  onPreviewFrame(final byte[] data, Camera camera){
179         /*if (null != mStreamTask){
180             switch (mStreamTask.getStatus()){
181                 case RUNNING:
182                     Log.e(TAG, "onPreviewFrame Running");
183                     return;
184                 case PENDING:
185                     Log.e(TAG,"OnPreviewFrame Pending");
186                     mStreamTask.cancel(false);
187                     break;
188             }
189         }
190         mStreamTask = new StreamTask(data);
191         mStreamTask.execute((Void)null);*/
192
193
194         long endTime = System.currentTimeMillis();
195         mExecutor.execute(new Runnable() {
196             @Override
197             public void run() {
198                 long encodeTime = System.currentTimeMillis();
199                 ffmpeg.process(data);
200                 Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime));
201             }
202         });
203         Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:"
204                 + (endTime - previewTime) + "  " + Thread.currentThread().getName());
205         previewTime = endTime;
206
207     }
208
209     // private
210     private boolean checkCameraHardware(Context context) {
211         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
212     }
213
214     private static Camera getCameraInstance(){
215         Camera c = null;
216         try {
217             Log.e(TAG, "Open Camera");
218             c = Camera.open(0);
219             Camera.Parameters params = c.getParameters();
220             Log.e(TAG, "Camera parameters:  " + params.getPreviewSize().width + "x" + params.getPreviewSize().height);
221             // NV21 : 17, JPEG 256
222             Log.e(TAG, "Preview format (17 is NV21): " + params.getPreviewFormat() + ". Picture format(256 is JPEG): " + params.getPictureFormat());
223             List<int[]> fps = params.getSupportedPreviewFpsRange();
224             for(int[] i : fps){
225                 Log.e(TAG, "###  fps range : [" + i[0] + "," + i[1] + "]\n");
226             }
227
228
229
230             Camera.Parameters parameters = c.getParameters();
231             //List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
232             List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
233             for (Camera.Size cc : sizes){
234                 Log.e(TAG, "=== width: " + cc.width + ". height:" + cc.height);
235             }
236             Camera.Size cs = sizes.get(3);
237             params.setPreviewSize(cs.width, cs.height);
238             params.setPictureSize(cs.width, cs.height);
239             params.setPictureFormat(ImageFormat.NV21);
240             c.setParameters(params);
241         }
242         catch (Exception e){
243             e.printStackTrace();
244         }
245         return c;
246     }
247
248 }