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" />
public native int play(Object surface, String fname);
public native int push(Object surface);
public native int preview(Object surface);
+ public native String getPerfectDevice();
}
package ai.suanzi.rtmpclient;
+import android.app.Activity;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.support.v7.app.AppCompatActivity;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.content.Intent;
+import java.io.OutputStream;
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) {
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");
}
btn.setText(btn.getText().equals("Start") ? "Stop" : "Start");
}
- });
+ });*/
/*this.mCamera = getCameraInstance();
if(checkCameraHardware(this)) Log.e(TAG, "has cameras: " + Camera.getNumberOfCameras());
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);
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);
+ }
+
}
--- /dev/null
+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");
+ }
+
+}
--- /dev/null
+package ai.suanzi.rtmpclient;
+
+public class UsbCamera {
+}
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;
}
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);
sws_freeContext(img_convert_ctx);
av_free(pFrameYUV);
+ av_free(pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
//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) {
+
+}
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