capture video on usb camera and encode with libx264
[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.Executor;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
22
23
24
25 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{
26
27     private static final String TAG = "PENG";
28     private Ffmpeg ffmpeg = new Ffmpeg();
29     private Camera mCamera ;//= getCameraInstance();
30     private StreamTask mStreamTask;
31     private SurfaceHolder mHolder;
32     ExecutorService mExecutor = Executors.newSingleThreadExecutor();
33
34     @Override
35     protected void onCreate(Bundle savedInstanceState) {
36         super.onCreate(savedInstanceState);
37         setContentView(R.layout.activity_main);
38         Log.e(TAG, "Ffmpeg Version: " + ffmpeg.getVersion());
39
40         final Button btn = findViewById(R.id.button);
41         btn.setText("Start");
42         btn.setOnClickListener(new View.OnClickListener() {
43             @Override
44             public void onClick(View v) {
45                 Log.e(TAG, "Button " + btn.getText() + " onClick");
46                 if (mCamera == null) return;
47                 if(btn.getText().equals("Start")){
48                     mCamera.startPreview();
49                     Camera.Parameters params = mCamera.getParameters();
50                     //params.setPreviewFpsRange(30000, 30000);
51                     //params.setPictureSize(320, 240);
52                     //params.setPictureFormat(ImageFormat.NV21);
53                     //mCamera.setParameters(params);
54
55
56
57
58                     ffmpeg.init(params.getPictureSize().width, params.getPictureSize().height);
59                 } else {
60                     mCamera.setPreviewCallback(null);
61                     Toast.makeText(MainActivity.this, "encode done", Toast.LENGTH_SHORT).show();
62                     ffmpeg.flush();
63                     ffmpeg.close();
64                 }
65                 btn.setText(btn.getText().equals("Start") ? "Stop" : "Start");
66             }
67         });
68
69         /*this.mCamera = getCameraInstance();
70         if(checkCameraHardware(this)) Log.e(TAG, "has cameras: " + Camera.getNumberOfCameras());
71 */
72         final SurfaceView surfaceView = findViewById(R.id.surfaceView);
73         mHolder = surfaceView.getHolder();
74         mHolder.addCallback(this);
75
76         //
77         //mCamera.setPreviewCallback(this);
78
79         /*try{
80             mCamera.setPreviewTexture(st);
81         }catch (IOException e){
82             e.printStackTrace();
83         }*/
84
85         final Button btn2 = findViewById(R.id.button2);
86         btn2.setOnClickListener(new View.OnClickListener(){
87             @Override
88             public void onClick(View view){
89                 Log.e(TAG, "onclick2");
90                 //ffmpeg.play(mHolder.getSurface(),"/storage/sdcard0/output.flv");
91                 ffmpeg.push(mHolder.getSurface());
92
93             }
94
95         });
96
97         Log.e(TAG, "onclick2");
98         //ffmpeg.play(mHolder.getSurface(),"/storage/emulated/0/Movies/output.flv");
99         //ffmpeg.play(mHolder.getSurface(),"/data/local/tmp/big_buck_bunny_720p_10mb.mp4");
100
101
102         btn2.post(new Runnable(){
103             @Override
104             public void run() {
105                 btn2.performClick();
106             }
107         });
108
109
110     }
111
112     //SurfaceTexture st = new SurfaceTexture(0);
113
114
115     @Override
116     protected void onPause(){
117         super.onPause();
118         Log.e(TAG, "OnPause");
119         //ffmpeg.flush();
120         //ffmpeg.close();
121     }
122
123     @Override
124     protected void onResume() {
125         super.onResume();
126         Log.e(TAG, "OnResume");
127     }
128
129     @Override
130     protected void onStop() {
131         super.onStop();
132         Log.e(TAG,"onStop");
133     }
134
135     @Override
136     protected void onStart(){
137         super.onStart();
138         Log.e(TAG,"onStart");
139     }
140
141     @Override
142     protected void onDestroy(){
143         super.onDestroy();
144         Log.e(TAG,"onDestroy");
145     }
146
147     @Override
148     protected void onRestart(){
149         super.onStart();
150         Log.e(TAG,"onRestart");
151     }
152
153     // class StreamTask AsyncTask
154     private class StreamTask extends AsyncTask<Void, Void, Void>{
155         private byte[] data;
156
157         StreamTask(byte[] data){
158             this.data = data;
159         }
160
161         @Override
162         protected Void doInBackground(Void... params) {
163
164             if (this.data != null){
165                 Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate());
166                 ffmpeg.process(this.data);
167             }
168             return null;
169         }
170     }
171
172     // SurfaceHolder.Callback implementation
173     @Override
174     public void surfaceCreated(final SurfaceHolder holder){
175         Log.e(TAG,"SurfacedCreated");
176         /*try {
177             mCamera.setPreviewDisplay(holder);
178             mCamera.startPreview();
179         } catch (IOException e) {
180             Log.d(TAG, "Error setting camera preview: " + e.getMessage());
181         }*/
182     }
183
184     @Override
185     public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
186         Log.e(TAG, "surfaceChanged");
187         //if(mCamera==null) return;
188         //Camera.Parameters parameters=mCamera.getParameters();
189         //parameters.setPreviewSize(640,480);
190         //parameters.setPictureSize(640,480);
191         //mCamera.setParameters(parameters);
192
193         //try{
194             //Thread.sleep(10000);
195             /*Log.e(TAG, "xxxxxxxxxxxxxx");
196             mExecutor.execute(new Runnable() {
197                 @Override
198                 public void run() {
199                     mCamera.startPreview();
200                     final Button btn = findViewById(R.id.button);
201                     Camera.Parameters params = mCamera.getParameters();
202                     ffmpeg.init(params.getPictureSize().width, params.getPictureSize().height);
203                 }
204             });*/
205
206             //btn.performClick();
207         //} catch (InterruptedException e){
208          //   e.printStackTrace();
209         //}
210
211
212
213         //Camera.Parameters params = mCamera.getParameters();
214         //ffmpeg.init(params.getPictureSize().width, params.getPictureSize().height);
215         /*Thread t = new Thread(new Runnable() {
216             @Override
217             public void run() {
218                 ffmpeg.play(mHolder.getSurface(),"/storage/emulated/0/Movies/output.flv");
219
220             }
221         });*/
222
223     }
224
225     @Override
226     public void surfaceDestroyed(SurfaceHolder holder){
227         Log.e(TAG, "surfaceDestroyed");
228     }
229
230     private long encodeCount = 0;
231     private long count = 0;
232     private long previewTime;
233     // Camera.PreviewCallback
234     @Override
235     public void  onPreviewFrame(final byte[] data, Camera camera){
236         /*if (null != mStreamTask){
237             switch (mStreamTask.getStatus()){
238                 case RUNNING:
239                     Log.e(TAG, "onPreviewFrame Running");
240                     return;
241                 case PENDING:
242                     Log.e(TAG,"OnPreviewFrame Pending");
243                     mStreamTask.cancel(false);
244                     break;
245             }
246         }
247         mStreamTask = new StreamTask(data);
248         mStreamTask.execute((Void)null);*/
249
250
251         /*long endTime = System.currentTimeMillis();
252         mExecutor.execute(new Runnable() {
253             @Override
254             public void run() {
255                 long encodeTime = System.currentTimeMillis();
256                 ffmpeg.process(data);
257                 Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime));
258             }
259         });
260         Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:"
261                 + (endTime - previewTime) + "  " + Thread.currentThread().getName());
262         previewTime = endTime;*/
263
264     }
265
266     // private
267     private boolean checkCameraHardware(Context context) {
268         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
269     }
270
271     private static Camera getCameraInstance(){
272         Camera c = null;
273         try {
274             Log.e(TAG, "Open Camera");
275             c = Camera.open(0);
276             Camera.Parameters params = c.getParameters();
277             Log.e(TAG, "Camera parameters:  " + params.getPreviewSize().width + "x" + params.getPreviewSize().height);
278             Log.e(TAG, "Preview format (17 is NV21): " + params.getPreviewFormat() + ". Picture format(256 is JPEG): " + params.getPictureFormat());
279             List<int[]> fps = params.getSupportedPreviewFpsRange();
280             for(int[] i : fps){
281                 Log.e(TAG, "###  fps range : [" + i[0] + "," + i[1] + "]\n");
282             }
283
284
285
286             Camera.Parameters parameters = c.getParameters();
287
288             List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
289             for (Camera.Size cc : sizes){
290                 Log.e(TAG, "=== width: " + cc.width + ". height:" + cc.height);
291             }
292             Camera.Size cs = sizes.get(3);
293             //params.setPreviewSize(cs.width, cs.height);
294             params.setPictureSize(cs.width, cs.height);
295             //params.setPictureFormat(ImageFormat.NV21);
296             c.setParameters(params);
297         }
298         catch (Exception e){
299             e.printStackTrace();
300         }
301         return c;
302     }
303
304 }