resize the preview size as the ratio of picture size
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MainActivity.java
1 package ai.suanzi.rtmpclient;
2
3 import android.content.IntentFilter;
4 import android.hardware.Camera;
5 import android.support.design.widget.TextInputEditText;
6 import android.support.v7.app.ActionBar;
7 import android.support.v7.app.AppCompatActivity;
8 import android.os.Bundle;
9 import android.util.DisplayMetrics;
10 import android.util.Log;
11 import android.view.SurfaceHolder;
12 import android.view.SurfaceView;
13 import android.view.View;
14 import android.view.Window;
15 import android.view.WindowManager;
16 import android.widget.Button;
17 import android.widget.Toast;
18 import android.content.Context;
19
20 import java.io.File;
21 import android.content.Intent;
22 import de.mindpipe.android.logging.log4j.LogConfigurator;
23 import org.apache.log4j.Level;
24 import org.apache.log4j.Logger;
25 import android.net.wifi.WifiManager;
26 import android.net.wifi.WifiInfo;
27 import android.content.ServiceConnection;
28 import android.content.ComponentName;
29
30 import ai.suanzi.rtmpclient.MyService.LocalBinder;
31 import android.os.IBinder;
32 import android.net.ConnectivityManager;
33 import android.view.ViewGroup;
34
35 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90";
36
37 public class MainActivity extends AppCompatActivity implements MyService.MyServiceEventListener, CameraView.Callback {
38
39     //private static final String TAG = "MainActivity";
40     private Logger gLogger;
41
42     private String mMacAddr = "";
43     private NetworkMonitor networkMonitor;
44     private UsbMonitor mUsbMonitor;
45     private ServiceHealthMonitor mServiceHealthMonitor;
46     private static final int INTERVAL = 3 * 60; // seconds
47
48     boolean mBounded = false;
49     MyService mServer;
50     Intent mIntent;
51
52     private CameraView mCameraView;
53
54     private void configLog(){
55         try {
56             final LogConfigurator logConfigurator = new LogConfigurator();
57             String fname = getExternalFilesDir(null) + File.separator + "log.txt";
58             logConfigurator.setFileName(fname);
59             logConfigurator.setRootLevel(Level.DEBUG);
60             logConfigurator.setLevel("org.apache", Level.ERROR);
61             logConfigurator.setMaxFileSize(1024 * 1024 * 10);
62             logConfigurator.configure();
63             gLogger = Logger.getLogger(getClass());
64             gLogger.error("#######################################");
65             gLogger.debug("Log file is located at: " + fname);
66
67         } catch (Exception e){
68             e.printStackTrace();
69         }
70     }
71
72     private void init(){
73         // set config file
74         UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
75
76         this.mMacAddr = getMacAddr();
77
78         mIntent = new Intent(this, MyService.class);
79         mUsbMonitor = new UsbMonitor(new UsbMonitor.UsbListener() {
80             @Override
81             public void onCameraConnected() {
82                 gLogger.error("onCameraConnected, current Usb Camera count: " + mUsbMonitor.getUsbCameraCount());
83                 doUnbindService();
84                 if(mUsbMonitor.hasUsbCamera()){
85                     doBindService();
86                 }
87             }
88
89             @Override
90             public void onCameraDisconnected() {
91                 gLogger.error("onCameraDisconnected, current camera count: " + mUsbMonitor.getUsbCameraCount());
92                 doUnbindService();
93                 if(mUsbMonitor.hasUsbCamera()){
94                     doBindService();
95                 }
96             }
97         }, this);
98
99         networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() {
100             @Override
101             public void onWifiConnected() {
102                 gLogger.error("onWifiConnected");
103                 doBindService();
104             }
105
106             @Override
107             public void onWifiDisconnected() {
108                 gLogger.error("onWifiDisconnected");
109                 doUnbindService();
110             }
111
112             @Override
113             public void onWifiEnabled() {
114                 gLogger.error("onWifiEnabled");
115             }
116
117             @Override
118             public void onWifiDisabled() {
119                 gLogger.error("onWifiDisabled");
120             }
121         });
122         IntentFilter filter = new IntentFilter();
123         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
124         registerReceiver(networkMonitor, filter);
125
126         mServiceHealthMonitor = new ServiceHealthMonitor(new ServiceHealthMonitor.Callback() {
127             @Override
128             public void onNotHealthy() {
129                 gLogger.error("onNotHealthy, in " + INTERVAL + " seconds, the publishing may stopped or have error ");
130                 doUnbindService();
131                 doBindService();
132             }
133         });
134         mServiceHealthMonitor.setInterval(INTERVAL); // 5 minutes
135     }
136
137
138     ServiceConnection mConnection = new ServiceConnection() {
139         @Override
140         public void onServiceDisconnected(ComponentName name) {
141             Toast.makeText(MainActivity.this, "Service is disconnected", 1000).show();
142             gLogger.error("onServiceDisconnected ---------->");
143             mBounded = false;
144             mServer = null;
145         }
146
147         @Override
148         public void onServiceConnected(ComponentName name, IBinder service) {
149             Toast.makeText(MainActivity.this, "Service is connected", 1000).show();
150             gLogger.error("onServiceConnected ---------->");
151             mBounded = true;
152             LocalBinder mLocalBinder = (LocalBinder)service;
153             mServer = mLocalBinder.getServiceInstance();
154             mServer.setServiceEventListener(MainActivity.this);
155             if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl(mMacAddr))){
156                 //mServer.startPreview(mHolder);
157                 mServer.startPreview(mCameraView.getHolder());
158                 Camera.Size cs = mServer.getBestPictureSize();
159                 mCameraView.setLayout(cs.width, cs.height);
160             }
161
162
163         }
164     };
165
166     private void doBindService(){
167         gLogger.debug("doBindService");
168         if(!mBounded && canStartService()) {
169             gLogger.debug("Start service --------->");
170             bindService(mIntent, mConnection, BIND_AUTO_CREATE);
171         }
172     }
173
174     private void doUnbindService() {
175         gLogger.debug("doUnbindService");
176         if(mBounded){
177             gLogger.debug("Stop service <---------");
178             unbindService(mConnection);
179             mBounded = false;
180         }
181     }
182
183     private void initCameraView (){
184         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
185         requestWindowFeature(Window.FEATURE_NO_TITLE);
186         getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
187         ///setContentView(R.layout.activity_main);
188
189         ActionBar actionBar = getSupportActionBar();
190         actionBar.hide();
191
192         DisplayMetrics outMetrics = new DisplayMetrics();
193         this.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
194
195         CameraView.SCREEN_WIDTH = outMetrics.widthPixels;
196         CameraView.SCREEN_HEIGHT = outMetrics.heightPixels;
197         gLogger.debug("Screen size is w: " + CameraView.SCREEN_WIDTH  + ", h: " + CameraView.SCREEN_HEIGHT);
198
199
200
201         mCameraView = new CameraView(getApplicationContext(), this);
202         setContentView(R.layout.activity_main);
203
204         ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(640, 480);
205         addContentView(mCameraView, lp);
206         //setContentView(mCameraView);
207     }
208     @Override
209     protected void onCreate(Bundle savedInstanceState) {
210         super.onCreate(savedInstanceState);
211         configLog();
212         //gLogger.debug("#######################################");
213         initCameraView();
214         init();
215         loadConfig();
216
217
218         if(NetworkMonitor.isNetworkAvailable(this) && mUsbMonitor.hasUsbCamera()){
219             gLogger.error("Current network is available");
220             doBindService();
221         } else {
222             gLogger.error("Current network NOT available or no USB Camera connected");
223         }
224
225         if(!mServiceHealthMonitor.isAlive()) {
226             gLogger.debug("mServiceHealthMonitor start, interval " + INTERVAL);
227             mServiceHealthMonitor.start();
228         }
229     }
230
231     @Override
232     protected void onPause(){
233         super.onPause();
234         gLogger.error("OnPause --------->");
235     }
236
237     @Override
238     protected void onResume() {
239         super.onResume();
240         gLogger.error("OnResume ---------> ");
241     }
242
243     @Override
244     protected void onStop() {
245         super.onStop();
246         gLogger.debug("onStop --------->");
247     }
248
249     @Override
250     protected void onStart(){
251         super.onStart();
252         gLogger.debug("onStart --------->");
253     }
254
255     @Override
256     protected void onDestroy(){
257         super.onDestroy();
258         mUsbMonitor.unregisterReceiver();
259         unregisterReceiver(networkMonitor);
260         unbindService(mConnection);
261         gLogger.debug("onDestroy --------->");
262     }
263
264     @Override
265     protected void onRestart(){
266         super.onRestart();
267         gLogger.debug("onRestart ---------->");
268     }
269
270     @Override
271     public void onBackPressed() {
272         gLogger.error("onBackPressed  --------->");
273         Intent intent = new Intent(Intent.ACTION_MAIN);
274         intent.addCategory(Intent.CATEGORY_HOME);
275         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
276         startActivity(intent);
277     }
278
279     private String getMacAddr() {
280         WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
281         WifiInfo info = manager.getConnectionInfo();
282         return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
283     }
284
285     private void loadConfig() {
286 //        UserInfo info = UserInfo.getConfig();
287 //        gLogger.error("server is:" + info.server);
288 //        mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" : info.server);
289 //        mTextUser.setText(info.user);
290 //        //mMacAddr = info.macAddr.equals("") ?  this.mMacAddr : info.macAddr;
291 //        gLogger.error("loadConfig - url is :" + info.toUrl(mMacAddr));
292     }
293
294     private void saveConfig() {
295         UserInfo info = UserInfo.getConfig();
296         //info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
297         if(info.saveConfig()) {
298             Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
299         } else {
300             Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
301         }
302         gLogger.error("saveConfig - url: " + info.toUrl(mMacAddr));
303     }
304
305     private boolean canStartService(){
306         return mUsbMonitor.hasUsbCamera() && NetworkMonitor.isNetworkAvailable(this);
307     }
308
309     // MyServiceEventListener
310     @Override
311     public void onCameraError(String msg){
312         gLogger.error("onCameraEvent " + msg);
313         //if(mUsbMonitor.hasUsbCamera()){
314             //mServer.reopenCamera();
315         //}
316     }
317
318     @Override
319     public void onEncoderError(String msg){
320         gLogger.error("onEncoderError: " + msg);
321         doUnbindService();
322         doBindService();
323     }
324
325     @Override
326     public void onPublishing(String msg){
327         mServiceHealthMonitor.record();
328     }
329
330     @Override
331     public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height){
332         if(mServer != null){
333             mServer.startPreview(holder);
334         }
335     }
336
337     private void restartApplication() {
338         final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
339         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
340         startActivity(intent);
341     }
342 }