X-Git-Url: http://47.100.26.94:8080/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fai%2Fsuanzi%2Frtmpclient%2FMyService.java;h=2637d609635f8f977935db83387c9e94a483be55;hb=8af8da070650175d3a35a840fbd339ee572d144f;hp=1d9dc6017892af45be562a16a38420fab8c5dbc0;hpb=f8fb13b9804d9b4b6fb227fbd07b80de9b092b55;p=rtmpclient.git diff --git a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java index 1d9dc60..2637d60 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java @@ -29,15 +29,18 @@ import android.view.Gravity; public class MyService extends Service implements Camera.PreviewCallback { - private Logger gLogger = Logger.getLogger("MyService"); + private static Logger gLogger = Logger.getLogger("MyService"); + private static String TAG = "MyService"; private Ffmpeg ffmpeg = Ffmpeg.getInstance(); private Boolean isRunning = false; - private FfmpegRunnable runnable; + //private FfmpegRunnable runnable; private Camera mCamera = null; IBinder mBinder = new LocalBinder(); - private WindowManager mWindowManager; - private SurfaceView mOutComeVideoView; + private String rtmpUrl; + //private WindowManager mWindowManager; + //private SurfaceView mOutComeVideoView; + private long frameCount = 0; public class LocalBinder extends Binder { @@ -46,43 +49,61 @@ public class MyService extends Service implements Camera.PreviewCallback { } } - private class FfmpegRunnable implements Runnable { - private String url; - private Camera.PreviewCallback cb; - public FfmpegRunnable(String _url, Camera.PreviewCallback _cb){ - this.url = _url; - this.cb = _cb; + public Camera getCameraInstance() { + if (mCamera == null) { + CameraHandlerThread mThread = new CameraHandlerThread("camera thread"); + synchronized (mThread) { + mThread.openCamera(); + } + } + if (mCamera == null){ + gLogger.error("getCameraInstance, camera is null"); + } + return mCamera; + } + + private void openCameraOriginal() { + try { + gLogger.error("openCameraOriginal"); + mCamera = Camera.open(1); + } catch (Exception e) { + gLogger.error("camera is not available. error: " + e.getMessage()); + } + } + + private class CameraHandlerThread extends HandlerThread { + Handler mHandler; + + public CameraHandlerThread(String name) { + super(name); + gLogger.error("CameraHandlerThread: " + name); + start(); + mHandler = new Handler(getLooper()); + } + + synchronized void notifyCameraOpened() { + notify(); } - @Override - public void run(){ - gLogger.error("Run Ffmpeg url: " + url); - isRunning = true; - //ffmpeg.push(null, this.url); - if (mCamera == null) { - gLogger.error("open camea"); - try { - mCamera = Camera.open(1); - }catch (Exception e){ - e.printStackTrace(); + + void openCamera() { + mHandler.post(new Runnable() { + @Override + public void run() { + openCameraOriginal(); + notifyCameraOpened(); } - } - /* - SurfaceTexture st = new SurfaceTexture(0); + }); try { - mCamera.setPreviewTexture(st); - }catch (Exception e){ - e.printStackTrace(); - }*/ - gLogger.error("start preview"); - mCamera.setPreviewCallback(this.cb); - mCamera.startPreview(); - + wait(); + } catch (InterruptedException e) { + gLogger.error("wait was interrupted"); + } } } private static final int NOTIFICATION_DOWNLOAD_PROGRESS_ID = 0x0001; //id不可设置为0,否则不能设置为前台service private void createNotification(){ - gLogger.error("createNotification"); + gLogger.debug("createNotification"); NotificationCompat.Builder builder=new NotificationCompat.Builder(this); //使用兼容版本 builder.setSmallIcon(R.mipmap.ic_launcher); //设置状态栏的通知图标 builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background)); //设置通知栏横条的图标 @@ -102,57 +123,31 @@ public class MyService extends Service implements Camera.PreviewCallback { @Override public void onCreate() { super.onCreate(); - gLogger.error("onCreate"); - - -// mWindowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); -// mOutComeVideoView = new SurfaceView(this); -// -// -// WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, -// WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT); -// layoutParams.gravity = Gravity.LEFT | Gravity.TOP; -// mWindowManager.addView(mOutComeVideoView, layoutParams); -// mOutComeVideoView.getHolder().addCallback(this); -// -// + gLogger.error("onCreate ---> "); createNotification(); - runnable = new FfmpegRunnable("xxxxxx", this); - new Thread(runnable).start(); - - - - + Toast.makeText(this, "Video stream pushed to " + this.rtmpUrl, Toast.LENGTH_LONG).show(); + mCamera = getCameraInstance(); + configCamera(mCamera); } @Override public void onDestroy() { stopForeground(true); - Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show(); - gLogger.error( "onDestroy"); super.onDestroy(); - + gLogger.error( "onDestroy --------->"); + Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show(); + if(mCamera != null){ + mCamera.stopPreview(); + mCamera.release(); + } } - @Override - public void onStart(Intent intent, int startid){ - super.onStart(intent, startid); - gLogger.error("onStart"); - - } @Override public int onStartCommand(Intent intent, int flags, int startId) { - String url = "hahahahhah"; //intent.getExtras().getString("url"); - - - gLogger.error("onStartCommand: url is:" + url + ". isRunning: " + isRunning); - runnable = new FfmpegRunnable(url, this); - if (!isRunning) { - createNotification(); - Toast.makeText(this, "Video stream pushed to " + url, Toast.LENGTH_LONG).show(); - new Thread(runnable).start(); - } + gLogger.error("onStartCommand"); + //nrunnable = new FfmpegRunnable("xxx", this); + //new Thread(runnable).start(); return START_STICKY; } @@ -165,49 +160,82 @@ public class MyService extends Service implements Camera.PreviewCallback { // Camera.PreviewCallback @Override public void onPreviewFrame(final byte[] data, Camera camera){ - gLogger.error("onPreviewFrame"); + if(frameCount % (15 * 60) == 0) { + gLogger.error("onPreviewFrame"); + } + frameCount++; ffmpeg.process(data); } - public void onChange (SurfaceHolder holder){ - gLogger.error("onChange"); + public void startPreview (SurfaceHolder holder){ + gLogger.error("startPreview"); + if (mCamera == null){ + gLogger.error("startPreview - error: camera is null"); + return; + } try { - if (holder == null){ - gLogger.error("xxxx holder is null xxxxxx"); - } - if (mCamera == null) { - gLogger.error("xxxx camera is null xxxx"); - } - mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (Exception e){ + gLogger.error("startPreview - error: " + e.getMessage()); e.printStackTrace(); } } + public boolean setRtmpUrl (String url){ + this.rtmpUrl = url; + Camera.Parameters param = mCamera.getParameters(); + int width = param.getPictureSize().width; + int height = param.getPictureSize().height; + gLogger.error("setRtmpUrl - size: " + width + "x" + height + ". url: " + url); + int ret = ffmpeg.initnew(width, height, url); + return ret == 0 ? true : false; + } + private void configCamera(Camera camera){ + if(mCamera == null){ + gLogger.error("configCamera - camera is null"); + return; + } + Camera.Parameters paras = camera.getParameters(); + gLogger.error("Supported Picture Sizes:"); + Camera.Size preferredSize = paras.getSupportedPictureSizes().get(0); + for (Camera.Size cc : paras.getSupportedPictureSizes()){ + if (cc.width == 640) + preferredSize = cc; + gLogger.error(cc.width + "x" + cc.height); + } + gLogger.error("Supported Preview fps range:"); + for(int[] i : paras.getSupportedPreviewFpsRange()){ + gLogger.error("[" + i[0] + "," + i[1] + "]"); + } + paras.setPictureSize(preferredSize.width, preferredSize.height); // use 640x480 preferred + camera.setParameters(paras); + camera.setDisplayOrientation(0); + gLogger.error("Preview Format: " + paras.getPreviewFormat() + ". Size: " + paras.getPreviewSize().width + "x" + paras.getPreviewSize().height); + gLogger.error("Picture Format: " + paras.getPictureFormat() + ". Size: " + paras.getPictureSize().width + "x" + paras.getPictureSize().height); + camera.setPreviewCallback(this); + //camera.startPreview(); + } +} -// // SurfaceHolder.Callback implementation -// @Override -// public void surfaceCreated(final SurfaceHolder holder){ -// gLogger.error("SurfacedCreated"); -// } -// -// @Override -// public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){ -// gLogger.error("surfaceChanged"); -// try { -// mCamera.setPreviewDisplay(holder); -// } catch (Exception e){ -// e.printStackTrace(); +// private class FfmpegRunnable implements Runnable { +// private String url; +// private Camera.PreviewCallback cb; +// public FfmpegRunnable(String _url, Camera.PreviewCallback _cb){ +// this.url = _url; +// this.cb = _cb; +// } +// @Override +// public void run(){ +// gLogger.error("Run Ffmpeg url: " + url); +// isRunning = true; +// gLogger.error("Open camera"); +// mCamera = getCameraInstance(); +// if(mCamera == null) { +// gLogger.error("Open camera, camera is null"); +// } +// configCamera(mCamera); +// mCamera.setPreviewCallback(this.cb); // } -// mCamera.startPreview(); -// -// } -// -// @Override -// public void surfaceDestroyed(SurfaceHolder holder){ -// gLogger.error("surfaceDestroyed"); // } -}