+
+ // Camera.PreviewCallback
+ @Override
+ public void onPreviewFrame(final byte[] data, Camera camera){
+ 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++;
+ }
+
+ public void startPreview (SurfaceHolder holder){
+ gLogger.debug("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();
+ if(mListener != null) mListener.onCameraError("setPreviewDisplay - " + e.getMessage());
+ }
+ }
+
+ public void reopenCamera() {
+ gLogger.debug("reopenCamera");
+ if(mCamera != null){
+ mCamera.stopPreview();
+ mCamera.release();
+ mCamera = null;
+ }
+ openCameraOriginal();
+ }
+
+ public boolean setRtmpUrl (String url){
+ //this.rtmpUrl = url;
+ if(mCamera == null || mPreferredSize == null){
+ gLogger.error("setRtmpUrl, error mCamera or PreferredSize is null");
+ return false;
+ }
+ gLogger.error("setRtmpUrl - size: " + mPreferredSize.width + "x" + mPreferredSize.height + ". url: " + url);
+ int ret = FfmpegHelper.initEncoder(mPreferredSize.width, mPreferredSize.height, url);
+ if(ret != 0){
+ gLogger.error("setRtmpUrl, initEncoder error");
+ }
+ return ret == 0 ? true : false;
+ }
+
+ private void configCamera(Camera camera){
+ 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;
+ }
+ gLogger.error("Supported Picture Sizes:");
+ Camera.Size preferredSize = paras.getSupportedPictureSizes().get(0);
+ for (Camera.Size cc : paras.getSupportedPictureSizes()){
+ if (cc.width == 640) // chose 640 x 480 if exists
+ 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] + "]");
+ }
+ mPreferredSize = preferredSize;
+ 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);
+ }
+
+ public Camera.Size getBestPictureSize(){
+ return mPreferredSize;
+ }
+
+ // 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;
+ }