pushing and previewing work when switch background/foreground
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MyService.java
1 package ai.suanzi.rtmpclient;
2
3 import android.app.Service;
4 import android.content.Intent;
5 import android.graphics.SurfaceTexture;
6 import android.hardware.Camera;
7 import android.os.Handler;
8 import android.os.HandlerThread;
9 import android.os.IBinder;
10 import android.os.Looper;
11 import android.util.Log;
12 import android.view.SurfaceHolder;
13 import android.view.SurfaceView;
14 import android.view.WindowManager;
15 import android.widget.Toast;
16 import android.support.v4.app.NotificationCompat;
17 import android.graphics.BitmapFactory;
18 import android.app.Notification;
19 import android.os.Message;
20 import org.apache.log4j.Level;
21 import org.apache.log4j.Logger;
22 import android.hardware.Camera.PreviewCallback;
23 import android.os.IBinder;
24 import android.os.Binder;
25 import android.content.Context;
26 import android.graphics.PixelFormat;
27 import java.io.IOException;
28 import android.view.Gravity;
29
30 public class MyService extends Service  implements Camera.PreviewCallback {
31
32     private Logger gLogger = Logger.getLogger("MyService");
33
34     private Ffmpeg ffmpeg = Ffmpeg.getInstance();
35     private  Boolean isRunning = false;
36     private FfmpegRunnable  runnable;
37     private Camera mCamera = null;
38     IBinder mBinder = new LocalBinder();
39     private WindowManager mWindowManager;
40     private SurfaceView mOutComeVideoView;
41
42
43     public class LocalBinder extends Binder {
44         public MyService getServiceInstance(){
45             return MyService.this;
46         }
47     }
48
49     private class FfmpegRunnable implements Runnable {
50         private String url;
51         private Camera.PreviewCallback cb;
52         public FfmpegRunnable(String _url, Camera.PreviewCallback _cb){
53             this.url = _url;
54             this.cb = _cb;
55         }
56         @Override
57         public void run(){
58             gLogger.error("Run Ffmpeg url: " + url);
59             isRunning = true;
60             //ffmpeg.push(null, this.url);
61             if (mCamera == null) {
62                 gLogger.error("open camea");
63                 try {
64                     mCamera = Camera.open(1);
65                 }catch (Exception e){
66                     e.printStackTrace();
67                 }
68             }
69             /*
70             SurfaceTexture st = new SurfaceTexture(0);
71             try {
72                 mCamera.setPreviewTexture(st);
73             }catch (Exception e){
74                 e.printStackTrace();
75             }*/
76             gLogger.error("start preview");
77             mCamera.setPreviewCallback(this.cb);
78             mCamera.startPreview();
79
80         }
81     }
82
83     private static final int NOTIFICATION_DOWNLOAD_PROGRESS_ID = 0x0001;                                        //id不可设置为0,否则不能设置为前台service
84     private void createNotification(){
85         gLogger.error("createNotification");
86         NotificationCompat.Builder builder=new NotificationCompat.Builder(this);                        //使用兼容版本
87         builder.setSmallIcon(R.mipmap.ic_launcher);                                                             //设置状态栏的通知图标
88         builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));   //设置通知栏横条的图标
89         builder.setAutoCancel(false);                                                                           //禁止用户点击删除按钮删除
90         builder.setOngoing(true);                                                                               //禁止滑动删除
91         builder.setShowWhen(true);                                                                              //右上角的时间显示
92         builder.setContentTitle("Rtmp Foreground Service!!!");                                                  //设置通知栏的标题内容
93         Notification notification = builder.build();                                                            //创建通知
94         startForeground(NOTIFICATION_DOWNLOAD_PROGRESS_ID,notification);                                        //设置为前台服务
95     }
96
97     @Override
98     public IBinder onBind(Intent intent) {
99         return mBinder;
100     }
101
102     @Override
103     public void onCreate() {
104         super.onCreate();
105         gLogger.error("onCreate");
106
107
108 //        mWindowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
109 //        mOutComeVideoView = new SurfaceView(this);
110 //
111 //
112 //        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
113 //                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
114 //        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
115 //        mWindowManager.addView(mOutComeVideoView, layoutParams);
116 //        mOutComeVideoView.getHolder().addCallback(this);
117 //
118 //
119         createNotification();
120         runnable = new FfmpegRunnable("xxxxxx", this);
121         new Thread(runnable).start();
122
123
124
125
126     }
127
128     @Override
129     public void onDestroy() {
130         stopForeground(true);
131         Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
132         gLogger.error( "onDestroy");
133         super.onDestroy();
134
135     }
136
137     @Override
138     public void onStart(Intent intent, int startid){
139         super.onStart(intent, startid);
140         gLogger.error("onStart");
141
142     }
143
144     @Override
145     public int onStartCommand(Intent intent, int flags, int startId) {
146         String url = "hahahahhah"; //intent.getExtras().getString("url");
147
148
149         gLogger.error("onStartCommand: url is:" + url + ". isRunning: " + isRunning);
150         runnable = new FfmpegRunnable(url, this);
151         if (!isRunning) {
152             createNotification();
153             Toast.makeText(this, "Video stream pushed to " + url, Toast.LENGTH_LONG).show();
154             new Thread(runnable).start();
155         }
156         return START_STICKY;
157     }
158
159     @Override
160     public void onLowMemory(){
161         super.onLowMemory();
162         gLogger.error("onLowMemory");
163     }
164
165     // Camera.PreviewCallback
166     @Override
167     public void  onPreviewFrame(final byte[] data, Camera camera){
168         gLogger.error("onPreviewFrame");
169         ffmpeg.process(data);
170     }
171
172     public void onChange (SurfaceHolder holder){
173         gLogger.error("onChange");
174         try {
175             if (holder == null){
176                 gLogger.error("xxxx holder is null xxxxxx");
177             }
178             if (mCamera == null) {
179                 gLogger.error("xxxx camera is null xxxx");
180             }
181
182             mCamera.setPreviewDisplay(holder);
183             mCamera.startPreview();
184         } catch (Exception e){
185             e.printStackTrace();
186         }
187     }
188
189
190
191 //    // SurfaceHolder.Callback implementation
192 //    @Override
193 //    public void surfaceCreated(final SurfaceHolder holder){
194 //        gLogger.error("SurfacedCreated");
195 //    }
196 //
197 //    @Override
198 //    public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
199 //        gLogger.error("surfaceChanged");
200 //        try {
201 //            mCamera.setPreviewDisplay(holder);
202 //        } catch (Exception e){
203 //            e.printStackTrace();
204 //        }
205 //        mCamera.startPreview();
206 //
207 //    }
208 //
209 //    @Override
210 //    public void surfaceDestroyed(SurfaceHolder holder){
211 //        gLogger.error("surfaceDestroyed");
212 //    }
213 }