fix bug when long runing in background v0.1.0
authorPeng Li <seudut@gmail.com>
Wed, 9 May 2018 04:20:48 +0000 (12:20 +0800)
committerPeng Li <seudut@gmail.com>
Wed, 9 May 2018 04:20:48 +0000 (12:20 +0800)
app/src/main/AndroidManifest.xml
app/src/main/java/ai/suanzi/rtmpclient/Ffmpeg.java
app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java
app/src/main/java/ai/suanzi/rtmpclient/MyService.java [new file with mode: 0644]
app/src/main/java/ai/suanzi/rtmpclient/UsbCamera.java [new file with mode: 0644]
app/src/main/jni/ai_suanzi_rtmpclient_Ffmpeg.cpp
app/src/main/jni/ai_suanzi_rtmpclient_Ffmpeg.h

index 19ba5b3..1468979 100644 (file)
@@ -9,6 +9,13 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
+        <service android:enabled="true"
+                    android:exported="true"
+                    android:name=".MyService">
+            <intent-filter>
+                <action android:name="ai.suanzi.rtmpclient.service" />
+            </intent-filter>
+        </service>
         <activity android:name=".MainActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
index e4eb05c..7d9bb80 100644 (file)
@@ -28,4 +28,5 @@ public class Ffmpeg {
     public native int play(Object surface, String fname);
     public native int push(Object surface);
     public native int preview(Object surface);
+    public native String getPerfectDevice();
 }
index cd42637..f7bb3a3 100644 (file)
@@ -1,5 +1,6 @@
 package ai.suanzi.rtmpclient;
 
+import android.app.Activity;
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.support.v7.app.AppCompatActivity;
@@ -20,6 +21,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import android.content.Intent;
+import java.io.OutputStream;
 
 
 
@@ -31,6 +33,9 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal
     private StreamTask mStreamTask;
     private SurfaceHolder mHolder;
     ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+    //Intent it = new Intent(getApplicationContext(), MyService.class);
+    Intent intent = new Intent();
+
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -40,7 +45,7 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal
 
         final Button btn = findViewById(R.id.button);
         btn.setText("Start");
-        btn.setOnClickListener(new View.OnClickListener() {
+        /*btn.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 Log.e(TAG, "Button " + btn.getText() + " onClick");
@@ -65,7 +70,7 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal
                 }
                 btn.setText(btn.getText().equals("Start") ? "Stop" : "Start");
             }
-        });
+        });*/
 
         /*this.mCamera = getCameraInstance();
         if(checkCameraHardware(this)) Log.e(TAG, "has cameras: " + Camera.getNumberOfCameras());
@@ -74,56 +79,35 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal
         mHolder = surfaceView.getHolder();
         mHolder.addCallback(this);
 
-        //
-        //mCamera.setPreviewCallback(this);
+        intent.setPackage(this.getPackageName());
+        intent.setAction("ai.suanzi.rtmpclient.service");
 
-        /*try{
-            mCamera.setPreviewTexture(st);
-        }catch (IOException e){
-            e.printStackTrace();
-        }*/
 
         final Button btn2 = findViewById(R.id.button);
+
+
         btn2.setOnClickListener(new View.OnClickListener(){
             @Override
             public void onClick(View view){
                 Log.e(TAG, "onclick2");
                 //ffmpeg.play(mHolder.getSurface(),"/storage/sdcard0/output.flv");
-                ffmpeg.push(mHolder.getSurface());
+                //ffmpeg.push(mHolder.getSurface());
                 //ffmpeg.preview(mHolder.getSurface());
-
+                // intent.putExtra("cmd",0);//0,开启前台服务,1,关闭前台服务
+                startService(intent);
             }
 
         });
 
-        Log.e(TAG, "onclick2");
-        /*
-        try {
-            Log.e(TAG, "Run command");
-            Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 666 /dev/video0"});
-            sh.waitFor();
-        }catch (Exception e){
-            e.printStackTrace();
-        }*/
-
-
-
-
-
         btn2.post(new Runnable(){
             @Override
             public void run() {
                 btn2.performClick();
+
             }
         });
 
-
-        Intent i = new Intent();
-        i.setAction(Intent.ACTION_MAIN);
-        i.addCategory(Intent.CATEGORY_HOME);
-        this.startActivity(i);
-
-
+        switchToBackground();
     }
 
     //SurfaceTexture st = new SurfaceTexture(0);
@@ -318,4 +302,29 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal
         return c;
     }
 
+    private void changeCameraPermission(){
+        Log.e(TAG, "change /dev/video0 permission");
+        try{
+            /*Process sh = Runtime.getRuntime().exec("su", null,null);
+            OutputStream  os = sh.getOutputStream();
+            os.write(("chmod 666 /dev/video0").getBytes("ASCII"));
+            os.flush();
+            os.close();
+            sh.waitFor();*/
+
+            Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"});
+            sh = Runtime.getRuntime().exec(new String[]{"chmod", "666", "/dev/video0"});
+            sh.waitFor();
+        } catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    private void switchToBackground(){
+        Intent i = new Intent();
+        i.setAction(Intent.ACTION_MAIN);
+        i.addCategory(Intent.CATEGORY_HOME);
+        this.startActivity(i);
+    }
+
 }
diff --git a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java
new file mode 100644 (file)
index 0000000..c5ec172
--- /dev/null
@@ -0,0 +1,125 @@
+package ai.suanzi.rtmpclient;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.util.Log;
+import android.widget.Toast;
+import android.support.v4.app.NotificationCompat;
+import android.graphics.BitmapFactory;
+import android.app.Notification;
+import android.os.Message;
+
+public class MyService extends Service {
+    private static final String TAG = "MyService";
+    private Ffmpeg ffmpeg = new Ffmpeg();
+    private  Boolean isRunning = false;
+
+    private Runnable runnable = new Runnable() {
+        @Override
+        public void run() {
+            Log.e(TAG, "Run ffmpeg");
+            isRunning = true;
+            ffmpeg.push(null);
+        }
+    };
+
+
+    /**
+     * 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);
+    }
+
+
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.e(TAG, "onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        stopForeground(true);
+        Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
+        Log.e(TAG, "onDestroy");
+        super.onDestroy();
+
+    }
+
+    @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);
+        return START_STICKY;
+    }
+
+    @Override
+    public void onLowMemory(){
+        super.onLowMemory();
+        Log.e(TAG, "onLowMemory");
+    }
+
+}
diff --git a/app/src/main/java/ai/suanzi/rtmpclient/UsbCamera.java b/app/src/main/java/ai/suanzi/rtmpclient/UsbCamera.java
new file mode 100644 (file)
index 0000000..0ca1023
--- /dev/null
@@ -0,0 +1,4 @@
+package ai.suanzi.rtmpclient;
+
+public class UsbCamera {
+}
index 760a062..59d4b6c 100644 (file)
@@ -477,8 +477,8 @@ JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_push (JNIEnv *env, jobje
     AVFormatContext *pFormatCtx = avformat_alloc_context();
 
     AVInputFormat *ifmt = av_find_input_format("video4linux2");
-    if(avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL) != 0) {
-        LOGE("could not open file11");
+    if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
+        LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
         return -1;
     }
 
@@ -621,21 +621,17 @@ JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_push (JNIEnv *env, jobje
 
                     int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
 
-                }
-
-
                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
                 //av_frame_free(&pFrameYUV);
                 //av_packet_unref(packet);
 
-                //av_free_packet(&enc_pkt);
+                av_free_packet(&enc_pkt);
+                //av_packet_unref(&enc_pkt);
+
+
+                }
+
 
-                /*
-                int y_size = pCodecCtx->width * pCodecCtx->height;
-                fwrite(pFrameYUV->data[0], 1, y_size, fp);      // Y
-                fwrite(pFrameYUV->data[1], 1, y_size / 4, fp);  // U
-                fwrite(pFrameYUV->data[2], 1, y_size / 4, fp);  // V
-                */
             }
         }
         av_packet_unref(packet);
@@ -643,6 +639,7 @@ JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_push (JNIEnv *env, jobje
 
     sws_freeContext(img_convert_ctx);
     av_free(pFrameYUV);
+    av_free(pFrame);
     avcodec_close(pCodecCtx);
     avformat_close_input(&pFormatCtx);
     return 0;
@@ -800,4 +797,8 @@ JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_preview (JNIEnv *env, jo
 
      //env->ReleaseStringUTFChars(fname, file_name);
     return 0;
-}
\ No newline at end of file
+}
+
+JNIEXPORT jstring JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_getPerfectDevice (JNIEnv *env, jobject obj) {
+
+}
index 9752077..2bdd6a7 100644 (file)
@@ -71,6 +71,14 @@ JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_push
 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_preview
   (JNIEnv *, jobject, jobject);
 
+/*
+ * Class:     ai_suanzi_rtmpclient_Ffmpeg
+ * Method:    getPerfectDevice
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_getPerfectDevice
+  (JNIEnv *, jobject);
+
 #ifdef __cplusplus
 }
 #endif