pushing and previewing work when switch background/foreground
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MainActivity.java
1 package ai.suanzi.rtmpclient;
2
3 import android.app.Activity;
4 import android.app.PendingIntent;
5 import android.content.BroadcastReceiver;
6 import android.content.IntentFilter;
7 import android.graphics.ImageFormat;
8 import android.graphics.SurfaceTexture;
9 import android.hardware.usb.UsbDevice;
10 import android.hardware.usb.UsbManager;
11 import android.os.Environment;
12 import android.support.design.widget.TextInputEditText;
13 import android.support.v7.app.AppCompatActivity;
14 import android.os.Bundle;
15 import android.text.TextUtils;
16 import android.util.Log;
17 import android.view.SurfaceHolder;
18 import android.hardware.Camera;
19 import android.view.SurfaceView;
20 import android.view.View;
21 import android.widget.Button;
22 import android.widget.Toast;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.os.AsyncTask;
26
27 import java.io.File;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.io.IOException;
32 import java.util.concurrent.Executor;
33 import java.util.concurrent.ExecutorService;
34 import java.util.concurrent.Executors;
35 import android.content.Intent;
36 import java.io.OutputStream;
37 import android.hardware.usb.UsbManager;
38 import android.hardware.usb.UsbDeviceConnection;
39
40 import de.mindpipe.android.logging.log4j.LogConfigurator;
41 import org.apache.log4j.Level;
42 import org.apache.log4j.Logger;
43 import android.net.wifi.WifiManager;
44 import android.net.wifi.WifiInfo;
45 import android.content.ServiceConnection;
46 import android.content.ComponentName;
47
48 import ai.suanzi.rtmpclient.MyService.LocalBinder;
49 import android.os.IBinder;
50
51 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
52
53 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{
54
55     private static final String TAG = "PENG";
56     private Ffmpeg ffmpeg;
57     private Camera mCamera ;
58     private StreamTask mStreamTask;
59     private SurfaceHolder mHolder;
60     private SurfaceView mSufaceView;
61     //private UVCCamera uvcCamera;
62     ExecutorService mExecutor = Executors.newSingleThreadExecutor();
63     //Intent it = new Intent(getApplicationContext(), MyService.class);
64     Intent intent = new Intent();
65
66     private UsbManager usbManager;
67     private UsbDevice usbCamera;
68
69     private Logger gLogger;
70
71     private Button mBtnStart;
72     private TextInputEditText mTextServer;
73     private TextInputEditText mTextUser;
74     private TextInputEditText mTextCamera;
75     private String mMacAddr = "";
76     private CameraView mCameraView;
77
78     private void configLog(){
79         try {
80             final LogConfigurator logConfigurator = new LogConfigurator();
81             String fname = getExternalFilesDir(null) + File.separator + "log.txt";
82             logConfigurator.setFileName(fname);
83             Log.e(TAG, "Log file is located at: " + fname);
84             logConfigurator.setRootLevel(Level.DEBUG);
85             logConfigurator.setLevel("org.apache", Level.ERROR);
86             logConfigurator.setMaxFileSize(1024 * 1024 * 10);
87             logConfigurator.configure();
88             gLogger = Logger.getLogger(getClass());
89         } catch (Exception e){
90             e.printStackTrace();
91         }
92     }
93
94     private void init(){
95         configLog();
96         gLogger.debug("#######################################");
97         UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
98         this.mMacAddr = getMacAddr();
99
100         ffmpeg = Ffmpeg.getInstance();
101         //uvcCamera = new UVCCamera();
102
103         mBtnStart = findViewById(R.id.button);
104         mTextServer = findViewById(R.id.textServer);
105         mTextUser = findViewById(R.id.textUser);
106         mTextCamera = findViewById(R.id.textCamera);
107         loadConfig();
108
109         // init service
110         intent.setPackage(this.getPackageName());
111         intent.setAction("ai.suanzi.rtmpclient.service");
112
113         // init surface view
114         mSufaceView = findViewById(R.id.surfaceView);
115         mHolder = mSufaceView.getHolder();
116         mHolder.addCallback(this);
117
118         // camera
119         //mCamera = getCameraInstance();
120         //configCamera(mCamera);
121
122     }
123
124
125     boolean mBounded;
126     MyService mServer;
127     ServiceConnection mConnection = new ServiceConnection() {
128         @Override
129         public void onServiceDisconnected(ComponentName name) {
130             Toast.makeText(MainActivity.this, "Service is disconnected", 1000).show();
131             gLogger.error("onServiceDisconnected");
132
133             mBounded = false;
134             mServer = null;
135         }
136
137         @Override
138         public void onServiceConnected(ComponentName name, IBinder service) {
139             Toast.makeText(MainActivity.this, "Service is connected", 1000).show();
140             gLogger.error("onServiceConnected");
141             mBounded = true;
142             LocalBinder mLocalBinder = (LocalBinder)service;
143             mServer = mLocalBinder.getServiceInstance();
144             mServer.onChange(mHolder);
145         }
146     };
147
148     @Override
149     protected void onCreate(Bundle savedInstanceState) {
150         super.onCreate(savedInstanceState);
151         setContentView(R.layout.activity_main);
152         init();
153         //mCameraView = new CameraView(this);
154         //intent.putExtra("url", "xxxxxxxxxxxxxxxxxx");
155         //intent.putExtra("view", mCameraView);
156
157         //startService(intent);
158         Intent mIntent = new Intent(this, MyService.class);
159         bindService(mIntent, mConnection, BIND_AUTO_CREATE);
160
161
162
163
164
165         mBtnStart.setOnClickListener(new View.OnClickListener(){
166             @Override
167             public void onClick(View view){
168                 String url = mTextServer.getText().toString() + "/" + mTextUser.getText().toString() + "_" + mMacAddr + "_" + mTextCamera.getText().toString();
169                 gLogger.error("----------> onClick, Url is: " + url);
170                 intent.putExtra("url", url);
171                 startService(intent);
172                 saveConfig();
173             }
174         });
175     }
176
177     @Override
178     protected void onPause(){
179         super.onPause();
180         gLogger.debug("OnPause");
181     }
182
183     @Override
184     protected void onResume() {
185         super.onResume();
186         gLogger.debug("OnResume");
187     }
188
189     @Override
190     protected void onStop() {
191         super.onStop();
192         gLogger.debug("onStop");
193     }
194
195     @Override
196     protected void onStart(){
197         super.onStart();
198         gLogger.debug("onStart");
199     }
200
201     @Override
202     protected void onDestroy(){
203         super.onDestroy();
204         gLogger.debug("onDestroy");
205     }
206
207     @Override
208     protected void onRestart(){
209         super.onStart();
210         gLogger.debug("onRestart");
211     }
212
213
214     // class StreamTask AsyncTask
215     private class StreamTask extends AsyncTask<Void, Void, Void>{
216         private byte[] data;
217
218         StreamTask(byte[] data){
219             this.data = data;
220         }
221
222         @Override
223         protected Void doInBackground(Void... params) {
224
225             if (this.data != null){
226                 Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate());
227                 ffmpeg.process(this.data);
228             }
229             return null;
230         }
231     }
232
233
234
235
236     // SurfaceHolder.Callback implementation
237     @Override
238     public void surfaceCreated(final SurfaceHolder holder){
239         gLogger.error("SurfacedCreated");
240     }
241
242     @Override
243     public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
244         gLogger.error("surfaceChanged");
245         mHolder = holder;
246
247         if (mServer != null) {
248             mServer.onChange(holder);
249         }
250
251        /* final SurfaceHolder hh = holder;
252         Thread tr = new Thread(new Runnable() {
253             @Override
254             public void run() {
255                 try {
256                     Thread.sleep(3000);
257                 } catch (Exception e){
258                     e.printStackTrace();
259                 }
260                 if (mServer != null) {
261                     gLogger.error("onChange");
262                     mServer.onChange(hh);
263                 }else {
264                     gLogger.error("service XXXXXXXXXXXXXXX");
265                 }
266
267             }
268         });
269         tr.run();*/
270
271
272      /*
273         try {
274             mCamera.setPreviewDisplay(holder);
275             mCamera.startPreview();
276         } catch (Exception e){
277             gLogger.error("Error starting camera previewe: " + e.getMessage());
278             Toast.makeText(this, "Camera Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
279         }
280         */
281     }
282
283     @Override
284     public void surfaceDestroyed(SurfaceHolder holder){
285         Log.e(TAG, "surfaceDestroyed");
286     }
287
288     @Override
289     public void  onPreviewFrame(final byte[] data, Camera camera){
290         gLogger.error("onPreviewFrame");
291         /*if (null != mStreamTask){
292             switch (mStreamTask.getStatus()){
293                 case RUNNING:
294                     Log.e(TAG, "onPreviewFrame Running");
295                     return;
296                 case PENDING:
297                     Log.e(TAG,"OnPreviewFrame Pending");
298                     mStreamTask.cancel(false);
299                     break;
300             }
301         }
302         mStreamTask = new StreamTask(data);
303         mStreamTask.execute((Void)null);
304 */
305
306 //        ong endTime = System.currentTimeMillis();
307 //        mExecutor.execute(new Runnable() {
308 //            @Override
309 //            public void run() {
310 //                //long encodeTime = System.currentTimeMillis();
311 //                ffmpeg.process(data);
312                 //Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime));
313 //            }
314 //        });
315         //Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:"
316 //                + (endTime - previewTime) + "  " + Thread.currentThread().getName());
317 //        previewTime = endTime;*/
318
319     }
320
321     // private
322     private boolean checkCameraHardware(Context context) {
323         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
324     }
325
326     private static Camera getCameraInstance(){
327         Camera c = null;
328         try {
329             Log.e(TAG, "Open Camera");
330             c = Camera.open(1);
331         } catch (Exception e){
332             e.printStackTrace();
333         }
334         return c;
335     }
336
337     private void configCamera(Camera camera){
338         Camera.Parameters paras = camera.getParameters();
339         gLogger.error("Supported Picture Sizes:");
340         for (Camera.Size cc : paras.getSupportedPictureSizes()){
341             gLogger.error(cc.width + "x" + cc.height);
342         }
343         gLogger.error("Supported Preview fps range:");
344         for(int[] i : paras.getSupportedPreviewFpsRange()){
345             gLogger.error("[" + i[0] + "," + i[1] + "]");
346         }
347         gLogger.error("Set parameters");
348         camera.setParameters(paras);
349         camera.setDisplayOrientation(0);
350         gLogger.error("Preview Format: " + paras.getPreviewFormat() + ". Size: " + paras.getPreviewSize().width + "x" + paras.getPreviewSize().height);
351         gLogger.error("Picture Format: " + paras.getPictureFormat() + ". Size: " + paras.getPictureSize().width + "x" + paras.getPictureSize().height);
352
353         try {
354             camera.setPreviewDisplay(mHolder);
355         } catch (IOException e){
356             e.printStackTrace();
357         }
358         //camera.setPreviewCallback(this);
359     }
360
361     private void switchToBackground(){
362         Intent i = new Intent();
363         i.setAction(Intent.ACTION_MAIN);
364         i.addCategory(Intent.CATEGORY_HOME);
365         this.startActivity(i);
366     }
367
368     private String getMacAddr() {
369         WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
370         WifiInfo info = manager.getConnectionInfo();
371         return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
372     }
373
374     private void loadConfig() {
375         UserInfo info = UserInfo.getConfig();
376         mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" :  info.server);
377         mTextUser.setText(info.user.equals("") ? "suanzi" : info.user );
378         mTextCamera.setText(info.cameraId.equals("") ?  "001" : info.cameraId);
379         mMacAddr = info.macAddr.equals("") ?  this.mMacAddr : info.macAddr;
380         gLogger.debug("loadConfig " + info.toString());
381     }
382
383     private void saveConfig() {
384         UserInfo info = UserInfo.getConfig();
385         info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
386         if(info.saveConfig()) {
387             Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
388         } else {
389             Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
390         }
391         gLogger.error("saveConfig: " + info.toString());
392     }
393
394     private void changePermission(){
395         try {
396             Log.e(TAG, "change permission");
397             //Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 666 /dev/video0"});
398
399             Process sh = Runtime.getRuntime().exec("/system/xbin/su", null,null);
400             //Process sh = Runtime.getRuntime().exec("su", null,null);
401
402             OutputStream  os = sh.getOutputStream();
403             os.write(("/system/bin/chmod 666 /dev/video0").getBytes("ASCII"));
404             //os.write(("/system/bin/echo 'wowo' >> /data/local/test").getBytes("ASCII"));
405             os.flush();
406             os.close();
407             sh.waitFor();
408
409
410         }catch (Exception e){
411             e.printStackTrace();
412         }
413     }
414 }