huangxinbao

handle publisher Video and audio,getAudioPath get Video path

... ... @@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
... ... @@ -207,6 +207,9 @@ public class VideoPlayActivity extends AppCompatActivity {
case "audio_stop":
break;
default:{
XdyLogUtil.e("xuedianyunlog",response);
}
}
}
});
... ...
... ... @@ -26,6 +26,7 @@ package com.mang.xdy.demo.activity;
import com.eventhandle.SmartEventCallback;
import com.google.gson.Gson;
import com.mang.xdy.common.Constants;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter;
... ... @@ -119,8 +120,9 @@ public class VideoPublisherActivity extends AppCompatActivity {
break;
case 6:
//推流video
publisherVideo((String) msg.obj);
// publisherVideo((String) msg.obj);
// publisherVideoText();
// publisherAudioText();
break;
case 7:
//停止播放
... ... @@ -166,15 +168,15 @@ public class VideoPublisherActivity extends AppCompatActivity {
//只有加入课堂成功才可以点击推流的按钮
handler.sendEmptyMessage(8);
break;
case "live":
// case "live":
// case "publishVideo":
// String urls= "rtmp://player.daniulive.com:1935/hls/stream";;
//推流直播
Message message1=Message.obtain();
message1.obj = response;
message1.what = 6;
handler.sendMessage(message1);
break;
// Message message1=Message.obtain();
// message1.obj = response;
// message1.what = 6;
// handler.sendMessage(message1);
// break;
case "video_stop":
// handler.sendEmptyMessage(7);
break;
... ... @@ -296,10 +298,22 @@ public class VideoPublisherActivity extends AppCompatActivity {
String s = XdyStringUtils.stringToJson(tem, true);
XdySdk.setAsyncApi(ids_new, s);
}
/**
* 获取封装的推流地址
*/
public void publisherVideoText(){
XdySdk.setAsyncApi("publishVideo", "", surfaceview_pubisherVideo, VideoPublisherActivity.this,"");
// XdySdk.setAsyncApi("publishVideo", "", surfaceview_pubisherVideo, VideoPublisherActivity.this,"");
}
/**
* 测试Audio
*/
public void publisherAudioText(){
XdySdk.setAsyncApi(Constants.PUBLISH_AUDIO, "", surfaceview_pubisherVideo, VideoPublisherActivity.this,"");
}
public void publisherVideo(String response) {
String url = XdyStringUtils.stringToJson(response);
XdyLogUtil.e("调用任务了播url:", "" + url);
... ... @@ -364,7 +378,9 @@ public class VideoPublisherActivity extends AppCompatActivity {
handler.sendEmptyMessage(4);
break;
case R.id.btn_videoPlay_pubsherVideo:
getPublish();
// getPublish();
// publisherVideoText();
publisherAudioText();
ToastUtil.showToastshort("推送视频",VideoPublisherActivity.this);
btnVideoPlayPubsherVideo.setClickable(false);
break;
... ...
package com.mang.xdy.bean;
/**
* Created by abao on 2017/4/13.
*/
public class ErrorCodeEntity {
/**
* code : 898
* reson :
*/
private int code;
private String reson;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getReson() {
return reson;
}
public void setReson(String reson) {
this.reson = reson;
}
}
... ...
... ... @@ -2,6 +2,7 @@ package com.mang.xdy.bean;
/**
* Created by abao on 2017/4/7.
* 考虑可能改变数据类型,与video 不公用
*/
public class GetPublishPathReceiveBean {
... ...
package com.mang.xdy.bean;
// FIXME generate failure method set and get MediaId
// FIXME generate failure field _$Replay151
// FIXME generate failure field _$RtmpUrl165
// FIXME generate failure field _$M3u8Url177
// FIXME generate failure field _$UserName168
/**
* Created by huang on 2017/4/9.
*/
... ...
... ... @@ -22,10 +22,8 @@ import com.mang.xdy.utils.XdyLogUtil;
*/
public class XdyJsCore {
private WebView mWebView;
private static String TAG="xdyjscore";
private static XdyJsCore mXdyCore;
/*同步调用方法返回值*/
private String revalue="";
/**
* 异步对外回调接口,所有回调都在此完成
*/
... ... @@ -107,12 +105,11 @@ public class XdyJsCore {
* @param parameter
*/
protected void native2js(final String id, String parameter){
revalue="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.evaluateJavascript("javascript:_native2js('" + id + "','"+parameter+"')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
XdyLogUtil.e("natice_js 同步", "" + value + "");
XdyLogUtil.e(TAG, value);
//TODO
// if (!TextUtils.isEmpty(value)&&value.length()>10) {
// if(mOnXdyAsyncMessageListener !=null){
... ...
... ... @@ -15,6 +15,9 @@ import android.view.SurfaceView;
import com.daniulive.smartpublisher.SmartPublisherJni;
import com.eventhandle.SmartEventCallback;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.common.Constants;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.voiceengine.NTAudioRecord;
... ... @@ -75,9 +78,9 @@ public class XdyPublisherCore implements SurfaceHolder.Callback, Camera.PreviewC
// if(isStart){
// return;
// }
// if (xdyPublisher == null) {
if (xdyPublisher == null) {
xdyPublisher = new SmartPublisherJni();
// }
}
isStart=true;
pubSurfaceViewHolder = mSurfaceView.getHolder();
pubSurfaceViewHolder.addCallback(this);
... ... @@ -139,15 +142,19 @@ public class XdyPublisherCore implements SurfaceHolder.Callback, Camera.PreviewC
// if(isStart){
// return;
// }
// if (xdyPublisher == null) {
if (xdyPublisher == null) {
xdyPublisher = new SmartPublisherJni();
// }
}
isStart=true;
Log.e(TAG, "surfaceCreated..");
int i = xdyPublisher.SmartPublisherInit(mActivity, audio_opt,video_opt, videoWidth, videoHight);
Log.e(TAG, "SmartPublisherInit:初始化返回值是0成功: " + i);
if(i!=0){
Log.e(TAG, "SmartPublisherInit:初始化返回值是0成功: " + i);
return;
}
xdyPublisher.SetSmartPublisherEventCallback(smartEventCallback);
if (xdyPublisher.SmartPublisherSetURL(rtmpUrl) != 0) {
Log.e(TAG, "Failed to set publish stream URL..");
... ...
... ... @@ -2,7 +2,6 @@ package com.mang.xdy.core;
import android.app.Activity;
import android.content.Context;
import android.nfc.Tag;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
... ... @@ -10,25 +9,26 @@ import android.util.Log;
import android.view.SurfaceView;
import com.eventhandle.SmartEventCallback;
import com.google.gson.JsonNull;
import com.mang.xdy.bean.AudioPlayBean;
import com.mang.xdy.bean.GetPublishPathReceiveBean;
import com.mang.xdy.bean.PublisherVideoReturnBean;
import com.mang.xdy.bean.VideoPlayBean;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.common.Constants;
import com.mang.xdy.message.MsgManage;
import com.mang.xdy.utils.JsonUtil;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import java.io.FileNotFoundException;
import static com.mang.xdy.utils.PlayerUtils.getPublishPath;
import static com.mang.xdy.utils.PlayerUtils.getPublishPathAudio;
import static com.mang.xdy.utils.PlayerUtils.getPublishPathVideo;
/**
* 对外调用的接口
* Created by abao on 2017/3/31.
* 受原先的文档设计的规则,所有方法的都是静态的方法,影响性能
* 考虑跟换文档,提升性能
*/
public class XdySdk {
/**
... ... @@ -39,8 +39,11 @@ public class XdySdk {
private static Context mContext;
private static XdyPlayerCore mXdyPlayerCore;
private static XdyPublisherCore mXdyPublisherCore;
/*消息管理*/
private static MsgManage mMsgManage;
public static String TAG="xdysdk";
/*缓存管理*/
private static ACache aCache;
//TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏)
private static SurfaceView mSurfaceView;
... ... @@ -84,12 +87,21 @@ public class XdySdk {
}
mContext=context;
mXdyJsCore = XdyJsCore.getInstance(context);
mMsgManage=MsgManage.getErrorMsgInstance();
mMsgManage.setXdyMsgManageListener(new MsgManage.OnXdyMsgManageListener() {
@Override
public void onXdyMsgResponse(String type, String response) {
//处理数据异常,传递给最外层
handleListener(type,response);
}
});
mXdyJsCore.setXdyAsyncMessageListener(new XdyJsCore.OnXdyAsyncMessageListener() {
@Override
public void getSdyAsyncMessageListener(String id, String parameter) {
handleData(id,parameter);
}
});
aCache=ACache.get(mContext);
}
/**
... ... @@ -132,40 +144,6 @@ public class XdySdk {
// break;
}
}
/**
* 重载推流
* @param type
* @param rtmpUrl
* @param surfaceView
* @param activity
* @deprecated
*/
public static void setAsyncApi(String type, String rtmpUrl, SurfaceView surfaceView, Activity activity) {
switch (type) {
case "playVideo":
//播放音频
case "playAudio":
//播放视频
// mXdyPlayerCore = new XdyPlayerCore(rtmpUrl,surfaceView, activity);
// mXdyPlayerCore= XdyPlayerCore.getXdyPlayerCore(rtmpUrl,surfaceView, activity);
// mXdyPlayerCore.playVideo(rtmpUrl, surfaceView,su);
break;
// case "publishVideo":
// //打开推流视频
// if(mXdyPublisherCore==null)
// mXdyPublisherCore=new XdyPublisherCore(1,1,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisher(rtmpUrl,surfaceView);
// break;
//
// case "publishAudio":
// //只推送音频
// if(mXdyPublisherCore==null)
// mXdyPublisherCore=new XdyPublisherCore(1,0,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisherAudio(rtmpUrl);
// break;
}
}
/**
* 重载推流
... ... @@ -265,13 +243,15 @@ public class XdySdk {
* 3,推流成功告知后台,和用户
*
*/
getPublishPath();
getPublishPathVideo();
mSurfaceView=surfaceView;
mActivity=activity;
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
getPublishPath();
getPublishPathAudio();
mSurfaceView=surfaceView;
mActivity=activity;
// if(mXdyPublisherCore==null)
// mXdyPublisherCore=new XdyPublisherCore(1,0,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisherAudio(rtmpUrl,smartEventCallback);
... ... @@ -343,26 +323,35 @@ public class XdySdk {
case Constants.GET_VIDEO_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(response,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null&&getPublishPathReceiveBean.getCode()==0){
String publishPath=XdyStringUtils.stringToJson(response);
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null) {
//可以推流了
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
String video_url=getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.GET_VIDEO_PUBLISH_PATH,video_url);
//判断
if (mSurfaceView==null){
//todo 输出提示
return;
if (getPublishPathReceiveBean.getCode() == 0) {
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
String video_url = getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.GET_VIDEO_PUBLISH_PATH, video_url);
//判断
if (mSurfaceView == null) {
//todo 输出提示
return;
}
if (mActivity == null) {
//TODo 给出提示
return;
}
if (mXdyPublisherCore == null)
mXdyPublisherCore = new XdyPublisherCore(1, 1, video_url, mSurfaceView, mActivity);
mXdyPublisherCore.publisher(video_url, new EventHande());
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessVideo(video_url);
}else{
mMsgManage.getPublishVideoPathError();
}
if(mActivity==null){
//TODo 给出提示
return;
}
if(mXdyPublisherCore==null)
mXdyPublisherCore=new XdyPublisherCore(1,1,video_url,mSurfaceView,mActivity);
mXdyPublisherCore.publisher(video_url,new EventHande());
}else{
//给出提示
mMsgManage.getPublishVideoPathError();
}
// mXdyPublisherCore=new XdyPublisherCore(1,1,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisher(rtmpUrl,smartEventCallback);
... ... @@ -370,7 +359,8 @@ public class XdySdk {
case Constants.GET_AUDIO_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(response,GetPublishPathReceiveBean.class);
String audio_path=XdyStringUtils.stringToJson(response);
GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(audio_path,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean_Audio!=null&&getPublishPathReceiveBean_Audio.getCode()==0){
//可以推流了
String audio_url=getPublishPathReceiveBean_Audio.getPublishUrl();
... ... @@ -386,27 +376,42 @@ public class XdySdk {
return;
}
if(mXdyPublisherCore==null)
mXdyPublisherCore=new XdyPublisherCore(1,1,audio_url,mSurfaceView,mActivity);
mXdyPublisherCore.publisher(audio_url,new EventHande());
mXdyPublisherCore=new XdyPublisherCore(1,0,audio_url,mSurfaceView,mActivity);
mXdyPublisherCore.publisherAudio(audio_url,new EventHande());
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessAudio(audio_url);
}else{
//给出提示
mMsgManage.getPublishVideoPathError();
}
// mXdyPublisherCore=new XdyPublisherCore(1,1,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisher(rtmpUrl,smartEventCallback);
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
// if(mXdyPublisherCore==null)
// mXdyPublisherCore=new XdyPublisherCore(1,0,rtmpUrl,surfaceView,activity);
// mXdyPublisherCore.publisherAudio(rtmpUrl,smartEventCallback);
//接收后台是否接收到推流URl的地址
String publishReplay_Audio=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay_Audio));
PublisherVideoReturnBean publisherVideoReturnBean_audio=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay_Audio),PublisherVideoReturnBean.class);
if(publisherVideoReturnBean_audio!=null&&publisherVideoReturnBean_audio.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}
break;
case Constants.PUBLISH_VIDEO:
//接收发送推流地址给后台返回的信息
String publishReplay=response;
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class);
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay));
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay),PublisherVideoReturnBean.class);
if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
... ... @@ -468,6 +473,12 @@ public class XdySdk {
mXdyPublisherCore.onStopPublisher();
mXdyPublisherCore=null;
}
if(mSurfaceView!=null){
mSurfaceView=null;
}
if(mActivity!=null){
mActivity=null;
}
}
static class EventHande implements SmartEventCallback {
... ... @@ -476,6 +487,7 @@ public class XdySdk {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.i(TAG, "开始。。");
mMsgManage.getPublishVideoPathError();
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.i(TAG, "连接中。。");
... ... @@ -486,7 +498,7 @@ public class XdySdk {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.i(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
PlayerUtils.setPublishSendSuccess(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.i(TAG, "连接断开。。");
... ...
package com.mang.xdy.message;
/**
* Created by abao on 2017/4/13.
*/
public class ErrorCode {
}
... ...
package com.mang.xdy.message;
import com.google.gson.Gson;
import com.mang.xdy.bean.ErrorCodeEntity;
/**
* Created by abao on 2017/4/13.
* 对外返回错误信息
*
*/
public class MsgManage {
private MsgManage(){}
private static class ErrorInner{
private final static MsgManage ERROR_MANAGE =new MsgManage();
}
public static MsgManage getErrorMsgInstance(){
return ErrorInner.ERROR_MANAGE;
}
public void sendErrroMsg(String ss){
}
public interface OnXdyMsgManageListener{
/**
* 返回的类型,和信息
* @param type
* @param response
*/
void onXdyMsgResponse(String type,String response);
}
private OnXdyMsgManageListener mOnXdyMsgManageListener;
public void setXdyMsgManageListener(OnXdyMsgManageListener onXdyMsgManageListener){
mOnXdyMsgManageListener=onXdyMsgManageListener;
}
/**
* 生成错误信息字符json字符串
* @param errorCode
* @param errorMsg
* @return
*/
public String parseErroJson(int errorCode,String errorMsg){
ErrorCodeEntity errorCodeEntity=new ErrorCodeEntity();
errorCodeEntity.setCode(errorCode);
errorCodeEntity.setReson(errorMsg);
String response=new Gson().toJson(errorCodeEntity);
return response;
}
/**
* 对外发布消息
* @param type
* @param response
*/
public void setMsg(String type,String response){
if(mOnXdyMsgManageListener!=null){
mOnXdyMsgManageListener.onXdyMsgResponse(type,response);
}
}
/**
* 获取视频推流地址失败
*/
public void getPublishVideoPathError(){
String mess= parseErroJson(1,"获取视频推流地址错误");
setMsg("xdysdk",mess);
}
}
... ...
... ... @@ -16,23 +16,46 @@ public class PlayerUtils {
*获取推流地址
* 这个地址的接收目前在同步的接口,后期做异步处理
* */
public static void getPublishPath() {
public static void getPublishPathVideo() {
String tem = "{ \"type\": \"live\"}";
String s = XdyStringUtils.stringToJson(tem, true);
XdySdk.setAsyncApi(Constants.GET_VIDEO_PUBLISH_PATH, s);
}
/**
* 向后台发送推流成功的信息
* 获取音频推流地址
*/
public static void getPublishPathAudio() {
String tem = "{ \"type\": \"live\"}";
String s = XdyStringUtils.stringToJson(tem, true);
XdySdk.setAsyncApi(Constants.GET_AUDIO_PUBLISH_PATH, s);
}
/**
* 向后台发送推流(Video)成功的信息
* @param url
*/
public static void setPublishSendSuccess(String url) {
public static void setPublishSendSuccessVideo(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
String pamp = new Gson().toJson(url);
String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("推流成功", "" + pamp);
XdySdk.setAsyncApi(Constants.PUBLISH_VIDEO, pamp);
}
}
/**
* 向后台发送推流数据(Auido)成功信息
* @param url
*/
public static void setPublishSendSuccessAudio(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("推流成功", "" + pamp);
XdySdk.setAsyncApi(Constants.PUBLISH_AUDIO, pamp);
}
}
}
... ...