X-Git-Url: http://47.100.26.94:8080/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fai%2Fsuanzi%2Frtmpclient%2FMyService.java;h=a9ef972efd35e53b25660a2a04cd7114a11f5328;hb=7a99b2b0d2cf8048e1d9dd7fae5ccf984a865b1e;hp=768d95d4a990bac0caa41ec06bec1ba75b9ad100;hpb=b7202442677d0cf41e6e59870cd6c34e5619b8b9;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 768d95d..a9ef972 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java @@ -2,124 +2,217 @@ 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"; -public class MyService extends Service { - private static final String TAG = "MyService"; - private Ffmpeg ffmpeg = Ffmpeg.getInstance(); + //private Ffmpeg ffmpeg = Ffmpeg.getInstance(); + private FfmpegHelper helper; private Boolean isRunning = false; + private Camera mCamera = null; + IBinder mBinder = new LocalBinder(); + private String rtmpUrl; + private long frameCount = 0; - private Runnable runnable = new Runnable() { - @Override - public void run() { - Log.e(TAG, "Run ffmpeg"); - isRunning = true; - ffmpeg.push(null); + + public class LocalBinder extends Binder { + public MyService getServiceInstance(){ + return MyService.this; } - }; - - - /** - * id不可设置为0,否则不能设置为前台service - */ - private static final int NOTIFICATION_DOWNLOAD_PROGRESS_ID = 0x0001; - - //private boolean isRemove=false;//是否需要移除 - - /** - * Notification - */ - public void createNotification(){ - Log.e(TAG, "create notification"); - //使用兼容版本 - NotificationCompat.Builder builder=new NotificationCompat.Builder(this); - //设置状态栏的通知图标 - builder.setSmallIcon(R.mipmap.ic_launcher); - //设置通知栏横条的图标 - builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background)); - //禁止用户点击删除按钮删除 - builder.setAutoCancel(false); - //禁止滑动删除 - builder.setOngoing(true); - //右上角的时间显示 - builder.setShowWhen(true); - //设置通知栏的标题内容 - builder.setContentTitle("Rtmp Foreground Service!!!"); - //创建通知 - Notification notification = builder.build(); - //设置为前台服务 - startForeground(NOTIFICATION_DOWNLOAD_PROGRESS_ID,notification); } + 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(); + } + + void openCamera() { + mHandler.post(new Runnable() { + @Override + public void run() { + openCameraOriginal(); + notifyCameraOpened(); + } + }); + try { + 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.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)); //设置通知栏横条的图标 + builder.setAutoCancel(false); //禁止用户点击删除按钮删除 + builder.setOngoing(true); //禁止滑动删除 + builder.setShowWhen(true); //右上角的时间显示 + builder.setContentTitle("Rtmp Foreground Service!!!"); //设置通知栏的标题内容 + Notification notification = builder.build(); //创建通知 + startForeground(NOTIFICATION_DOWNLOAD_PROGRESS_ID,notification); //设置为前台服务 + } @Override public IBinder onBind(Intent intent) { - return null; + return mBinder; } @Override public void onCreate() { super.onCreate(); - Log.e(TAG, "onCreate"); + gLogger.error("onCreate ---> "); + createNotification(); + 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(); - Log.e(TAG, "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); - Log.e(TAG, "onStart"); - - } @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.e(TAG, "onStartCommand"); - if (!isRunning) { - createNotification(); - Toast.makeText(this, "Ffmpeg started", Toast.LENGTH_LONG).show(); - new Thread(runnable).start(); - } - -// int i=intent.getExtras().getInt("cmd"); -// if(i==0){ -// if(!isRemove) { -// -// createNotification(); -// } -// isRemove=true; -// }else { -// //移除前台服务 -// if (isRemove) { -// stopForeground(true); -// } -// isRemove=false; -// } - //super.onStartCommand(intent, flags, startId); + gLogger.error("onStartCommand"); + //nrunnable = new FfmpegRunnable("xxx", this); + //new Thread(runnable).start(); return START_STICKY; } @Override public void onLowMemory(){ super.onLowMemory(); - Log.e(TAG, "onLowMemory"); + gLogger.error("onLowMemory"); + } + + // Camera.PreviewCallback + @Override + public void onPreviewFrame(final byte[] data, Camera camera){ + if(frameCount % (15 * 60) == 0) { + gLogger.error("onPreviewFrame"); + } + frameCount++; + //ffmpeg.process(data); } + public void startPreview (SurfaceHolder holder){ + gLogger.error("startPreview"); + if (mCamera == null){ + gLogger.error("startPreview - error: camera is null"); + return; + } + try { + 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); + int ret = FfmpegHelper.initialEncoder(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); + } }