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 Ffmpeg ffmpeg = Ffmpeg.getInstance();
+ private FfmpegHelper helper;
private Boolean isRunning = false;
- private FfmpegRunnable runnable;
private Camera mCamera = null;
IBinder mBinder = new LocalBinder();
- private WindowManager mWindowManager;
- private SurfaceView mOutComeVideoView;
+ private String rtmpUrl;
+ private long frameCount = 0;
public class LocalBinder extends Binder {
}
}
- 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());
}
- @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();
+ }
+
+ 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();
}
- }
- /*
- 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)); //设置通知栏横条的图标
@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;
}
// Camera.PreviewCallback
@Override
public void onPreviewFrame(final byte[] data, Camera camera){
- gLogger.error("onPreviewFrame");
- ffmpeg.process(data);
+ 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);
+ int ret = FfmpegHelper.initialEncoder(width, height, url);
+ return ret == 0 ? true : false;
+ }
-
-// // 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();
-// }
-// mCamera.startPreview();
-//
-// }
-//
-// @Override
-// public void surfaceDestroyed(SurfaceHolder holder){
-// gLogger.error("surfaceDestroyed");
-// }
+ 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);
+ }
}