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