X-Git-Url: http://47.100.26.94:8080/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fai%2Fsuanzi%2Frtmpclient%2FMyService.java;h=2d49e9c6b19b47872a2b273d618397a7c3357198;hb=679195d4e27980faf7fd4ef577301b005ab054f1;hp=2637d609635f8f977935db83387c9e94a483be55;hpb=8af8da070650175d3a35a840fbd339ee572d144f;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 2637d60..2d49e9c 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java @@ -2,46 +2,37 @@ package ai.suanzi.rtmpclient; import android.app.Service; import android.content.Intent; -import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; -import android.os.Looper; -import android.util.Log; import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.WindowManager; import android.widget.Toast; import android.support.v4.app.NotificationCompat; import android.graphics.BitmapFactory; import android.app.Notification; -import android.os.Message; -import org.apache.log4j.Level; import org.apache.log4j.Logger; -import android.hardware.Camera.PreviewCallback; -import android.os.IBinder; import android.os.Binder; -import android.content.Context; -import android.graphics.PixelFormat; -import java.io.IOException; -import android.view.Gravity; -public class MyService extends Service implements Camera.PreviewCallback { - private static Logger gLogger = Logger.getLogger("MyService"); - private static String TAG = "MyService"; - private Ffmpeg ffmpeg = Ffmpeg.getInstance(); - private Boolean isRunning = false; - //private FfmpegRunnable runnable; +public class MyService extends Service implements Camera.PreviewCallback, Camera.ErrorCallback { + + private static Logger gLogger = Logger.getLogger("MyService"); private Camera mCamera = null; IBinder mBinder = new LocalBinder(); - private String rtmpUrl; - //private WindowManager mWindowManager; - //private SurfaceView mOutComeVideoView; + //private String rtmpUrl; private long frameCount = 0; + // Preferred picture Size of the camera; + private int width = 0; + private int height = 0; + + + private MyServiceEventListener mListener; + public void setServiceEventListener(MyServiceEventListener listener){ + mListener = listener; + } public class LocalBinder extends Binder { public MyService getServiceInstance(){ @@ -56,18 +47,34 @@ public class MyService extends Service implements Camera.PreviewCallback { mThread.openCamera(); } } - if (mCamera == null){ - gLogger.error("getCameraInstance, camera is null"); - } return mCamera; } private void openCameraOriginal() { try { gLogger.error("openCameraOriginal"); - mCamera = Camera.open(1); + Camera.CameraInfo info = new Camera.CameraInfo(); + int numCameras = Camera.getNumberOfCameras(); + int backId = -1; + int frontId = -1; + int camerId = 0; + gLogger.debug("Number of Cameras is " + numCameras); + for(int i = 0; i < numCameras; i++){ + Camera.getCameraInfo(i, info); + if(info.facing == Camera.CameraInfo.CAMERA_FACING_BACK){ + gLogger.debug("CAMERA_FACING_BACK id is " + i); + backId = i; + } else if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){ + gLogger.debug("CAMERA_FACING_FRONT id is " + i); + frontId = i; + } + } + if(frontId != -1) camerId = frontId; + else if(backId != -1) camerId = backId; + mCamera = Camera.open(camerId); } catch (Exception e) { - gLogger.error("camera is not available. error: " + e.getMessage()); + gLogger.error("openCameraOriginal - camera is not available. error: " + e.getMessage()); + if(mListener != null) mListener.onCameraError("openCamera - error: " + e.getMessage()); } } @@ -96,7 +103,7 @@ public class MyService extends Service implements Camera.PreviewCallback { try { wait(); } catch (InterruptedException e) { - gLogger.error("wait was interrupted"); + gLogger.error("wait was interrupted, " + e.getMessage()); } } } @@ -125,9 +132,13 @@ public class MyService extends Service implements Camera.PreviewCallback { super.onCreate(); gLogger.error("onCreate ---> "); createNotification(); - Toast.makeText(this, "Video stream pushed to " + this.rtmpUrl, Toast.LENGTH_LONG).show(); + Toast.makeText(this, "Started to Publish!", Toast.LENGTH_LONG).show(); mCamera = getCameraInstance(); - configCamera(mCamera); + if(mCamera != null){ + configCamera(mCamera); + mCamera.setErrorCallback(this); + } + } @Override @@ -146,8 +157,6 @@ public class MyService extends Service implements Camera.PreviewCallback { @Override public int onStartCommand(Intent intent, int flags, int startId) { gLogger.error("onStartCommand"); - //nrunnable = new FfmpegRunnable("xxx", this); - //new Thread(runnable).start(); return START_STICKY; } @@ -163,45 +172,62 @@ public class MyService extends Service implements Camera.PreviewCallback { if(frameCount % (15 * 60) == 0) { gLogger.error("onPreviewFrame"); } + if(FfmpegHelper.processFrame(data) != 0){ + gLogger.error("onPreviewFrame, processFrame close"); + FfmpegHelper.close(); + if(mListener != null) mListener.onEncoderError("processFrame"); + } else { + if(frameCount % (15 * 60) == 0){ + if(mListener != null) mListener.onPublishing("processFrame OK"); + } + } frameCount++; - ffmpeg.process(data); } public void startPreview (SurfaceHolder holder){ - gLogger.error("startPreview"); - if (mCamera == null){ - gLogger.error("startPreview - error: camera is null"); - return; - } + gLogger.debug("startPreview"); try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (Exception e){ gLogger.error("startPreview - error: " + e.getMessage()); e.printStackTrace(); + if(mListener != null) mListener.onCameraError("setPreviewDisplay - " + e.getMessage()); } } + public void reopenCamera() { + if(mCamera != null){ + mCamera.stopPreview(); + mCamera.release(); + } + openCameraOriginal(); + } + public boolean setRtmpUrl (String url){ - this.rtmpUrl = url; - Camera.Parameters param = mCamera.getParameters(); - int width = param.getPictureSize().width; - int height = param.getPictureSize().height; + //this.rtmpUrl = url; + if(mCamera == null) return false; gLogger.error("setRtmpUrl - size: " + width + "x" + height + ". url: " + url); - int ret = ffmpeg.initnew(width, height, url); + int ret = FfmpegHelper.initEncoder(width, height, url); + if(ret != 0){ + gLogger.error("setRtmpUrl, initEncoder error"); + } return ret == 0 ? true : false; } private void configCamera(Camera camera){ - if(mCamera == null){ - gLogger.error("configCamera - camera is null"); + Camera.Parameters paras = null; + try { + paras = camera.getParameters(); + } catch (RuntimeException e){ + gLogger.error("configCamera - " + e.getMessage()); + if(mListener != null) mListener.onCameraError("getParameters - " + e.getMessage()); 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) + if (cc.width == 640) // chose 640 x 480 if exists preferredSize = cc; gLogger.error(cc.width + "x" + cc.height); } @@ -209,33 +235,37 @@ public class MyService extends Service implements Camera.PreviewCallback { for(int[] i : paras.getSupportedPreviewFpsRange()){ gLogger.error("[" + i[0] + "," + i[1] + "]"); } + width = preferredSize.width; + height = preferredSize.height; 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(); } -} -// 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); -// } -// } + // Camaer.onError callback + @Override + public void onError(int error, Camera camera){ + gLogger.error("Camera.OnError, " + error); + switch (error) { + case Camera.CAMERA_ERROR_SERVER_DIED: + gLogger.error("CAMERA_ERROR_SERVER_DIED"); + break; + case Camera.CAMERA_ERROR_UNKNOWN: + gLogger.error("CAMERA_ERROR_UNKNOWN"); + break; + } + + if(mListener != null) mListener.onCameraError("OnError, " + error); + } + + + public interface MyServiceEventListener { + void onCameraError(String err); + void onEncoderError(String msg); + //void onIsPreviewing(String msg); // notify mainActivity if preview is running well + void onPublishing(String msg); // notify main activity if encoder is running well; + } +}