CMakeLists.txt 中添加相关cpp
GConnectListener
package com.example.glivepush.push;
public interface GConnectListener {
//
void onConnecting();
void onConnectSuccess();
void onConnectFail(String msg);
}
PushVideo
package com.example.glivepush.push;
import android.text.TextUtils;
public class PushVideo {
static {
System.loadLibrary("gpush");
}
private GConnectListener gConnectListener;
public void setgConnectListener(GConnectListener gConnectListener) {
this.gConnectListener = gConnectListener;
}
/********************************************************回调***********************************/
private void onConnecting() {
if (gConnectListener != null) {
gConnectListener.onConnecting();
}
}
private void onConnectSuccess() {
if (gConnectListener != null) {
gConnectListener.onConnectSuccess();
}
}
private void onConnectFail(String msg) {
if (gConnectListener != null) {
gConnectListener.onConnectFail(msg);
}
}
/********************************************************回调***********************************/
public void initLivePush(String url) {
if (!TextUtils.isEmpty(url)) {
initPush(url);
}
}
private native void initPush(String pushUrl);
}
LivePushActivity
package com.example.glivepush;
import android.os.Bundle;
import android.os.Environment;
import android.se.omapi.SEService;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.glivepush.push.GConnectListener;
import com.example.glivepush.push.PushVideo;
public class LivePushActivity extends AppCompatActivity {
private PushVideo pushVideo;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_push);
pushVideo = new PushVideo();
/********************************************************回调*******************************/
pushVideo.setgConnectListener(new GConnectListener() {
@Override
public void onConnecting() {
Log.d("godv", "链接服务器中");
}
@Override
public void onConnectSuccess() {
Log.d("godv", "链接服务器成功");
}
@Override
public void onConnectFail(String msg) {
Log.d("godv", msg);
}
});
/********************************************************回调*******************************/
}
public void startPush(View view) {
pushVideo.initLivePush("rtmp://192.168.0.14/myapp/mystream");
}
}
gpush.cpp
#include <jni.h>
#include <string>
#include "RtmpPush.h"
/********************************************************回调***************************************/
#include "GCallJava.h"
GCallJava *gCallJava = NULL;
JavaVM *javaVm = NULL;
/********************************************************回调***************************************/
RtmpPush *rtmpPush = NULL;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_glivepush_push_PushVideo_initPush(JNIEnv *env, jobject thiz, jstring pushUrl_) {
// TODO: implement initPush()
const char *pushUrl = env->GetStringUTFChars(pushUrl_, 0);
/********************************************************回调***********************************/
gCallJava = new GCallJava(javaVm, env, &thiz);
rtmpPush = new RtmpPush(pushUrl, gCallJava);
/********************************************************回调***********************************/
rtmpPush->init();
env->ReleaseStringUTFChars(pushUrl_, pushUrl);
}
/********************************************************回调***************************************/
extern "C"
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
javaVm = vm;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
return JNI_VERSION_1_6;
}
extern "C"
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved) {
javaVm = NULL;
}
/********************************************************回调***************************************/
GCallJava.h
#ifndef RTMPSUC_GCALLJAVA_H
#define RTMPSUC_GCALLJAVA_H
#include "jni.h"
#define G_THREAD_MAIN 1
#define G_THREAD_CHILD 2
class GCallJava {
public:
JNIEnv *jniEnv = NULL;
JavaVM *javaVm = NULL;
jobject jobj;
jmethodID jmid_connecting;
jmethodID jmid_connectsuccess;
jmethodID jmid_connectfail;
public:
GCallJava(JavaVM *javaVm, JNIEnv *jniEnv, jobject *jobj);
~GCallJava();
void onConnecting(int type);
void onConnectSuccess();
void onConnectFail(char *msg);
};
#endif //RTMPSUC_GCALLJAVA_H
GCallJava.cpp
#include "GCallJava.h"
GCallJava::GCallJava(JavaVM *javaVm, JNIEnv *jniEnv, jobject *jobj) {
this->javaVm = javaVm;
this->jniEnv = jniEnv;
this->jobj = jniEnv->NewGlobalRef(*jobj);
jclass jlz = jniEnv->GetObjectClass(this->jobj);
jmid_connecting = jniEnv->GetMethodID(jlz, "onConnecting", "()V");
jmid_connectsuccess = jniEnv->GetMethodID(jlz, "onConnectSuccess", "()V");
jmid_connectfail = jniEnv->GetMethodID(jlz, "onConnectFail", "(Ljava/lang/String;)V");
}
GCallJava::~GCallJava() {
jniEnv->DeleteGlobalRef(jobj);
javaVm = NULL;
jniEnv = NULL;
}
void GCallJava::onConnecting(int type) {
if (type == G_THREAD_CHILD) {
JNIEnv *jniEnv;
if (javaVm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
return;
}
jniEnv->CallVoidMethod(jobj, jmid_connecting);
javaVm->DetachCurrentThread();
} else {
jniEnv->CallVoidMethod(jobj, jmid_connecting);
}
}
void GCallJava::onConnectSuccess() {
JNIEnv *jniEnv;
if (javaVm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
return;
}
jniEnv->CallVoidMethod(jobj, jmid_connectsuccess);
javaVm->DetachCurrentThread();
}
void GCallJava::onConnectFail(char *msg) {
JNIEnv *jniEnv;
if (javaVm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
return;
}
jstring jmsg = jniEnv->NewStringUTF(msg);
jniEnv->CallVoidMethod(jobj, jmid_connectfail, jmsg);
jniEnv->DeleteLocalRef(jmsg);
javaVm->DetachCurrentThread();
}
RtmpPush.h
#ifndef RTMPSUC_RTMPPUSH_H
#define RTMPSUC_RTMPPUSH_H
#include <malloc.h>
#include <cstring>
#include "GQueue.h"
#include "pthread.h"
/********************************************************回调***************************************/
#include "GCallJava.h"
/********************************************************回调***************************************/
extern "C" {
#include "librtmp/rtmp.h"
};
class RtmpPush {
public:
RTMP *rtmp = NULL;
char *url = NULL;
GQueue *queue = NULL;
pthread_t push_thread;
/********************************************************回调***********************************/
GCallJava *gCallJava = NULL;
/********************************************************回调***********************************/
public:
/********************************************************回调***********************************/
RtmpPush(const char *url, GCallJava *gCallJava);
/********************************************************回调***********************************/
~RtmpPush();
void init();
};
#endif //RTMPSUC_RTMPPUSH_H
RtmpPush.cpp
#include "RtmpPush.h"
/********************************************************回调***************************************/
RtmpPush::RtmpPush(const char *url, GCallJava *gCallJava) {
this->url = static_cast<char *>(malloc(512));
strcpy(this->url, url);
this->queue = new GQueue();
this->gCallJava = gCallJava;
}
/********************************************************回调***************************************/
RtmpPush::~RtmpPush() {
queue->notifyQueue();
queue->clearQueue();
free(url);
}
void *callBackPush(void *data) {
RtmpPush *rtmpPush = static_cast<RtmpPush *>(data);
/********************************************************子线程回调******************************/
rtmpPush->gCallJava->onConnecting(G_THREAD_CHILD);
/********************************************************回调***********************************/
rtmpPush->rtmp = RTMP_Alloc(); //分配空间
RTMP_Init(rtmpPush->rtmp); //初始化
rtmpPush->rtmp->Link.timeout = 10; //设置超时时间
rtmpPush->rtmp->Link.lFlags |= RTMP_LF_LIVE; //追加直播
RTMP_SetupURL(rtmpPush->rtmp, rtmpPush->url); //设置推流URL
RTMP_EnableWrite(rtmpPush->rtmp); //设置可写状态
if (!RTMP_Connect(rtmpPush->rtmp, NULL)) { //链接服务器 0失败
// LOGE("can not connect the url %s", rtmpPush->url);
/********************************************************子线程回调**************************/
rtmpPush->gCallJava->onConnectFail("can not connect the url");
/*************************************************************回调**************************/
goto end;
}
if (!RTMP_ConnectStream(rtmpPush->rtmp, 0)) { //链接流 0失败
/********************************************************子线程回调**************************/
rtmpPush->gCallJava->onConnectFail("can not connect the stream of the service");
/********************************************************回调*******************************/
goto end;
}
//推流
/********************************************************子线程回调******************************/
rtmpPush->gCallJava->onConnectSuccess();
/********************************************************回调***********************************/
end:
RTMP_Close(rtmpPush->rtmp);
RTMP_Free(rtmpPush->rtmp);
rtmpPush->rtmp = NULL;
pthread_exit(&rtmpPush->push_thread);
}
void RtmpPush::init() {
/***************************************************主线程回调***********************************/
//gCallJava->onConnecting(G_THREAD_MAIN);
/********************************************************回调***********************************/
pthread_create(&push_thread, NULL, callBackPush, this);
}