huangxinbao

Modify push video will play their own problems

<component name="CopyrightManager">
<settings default="" />
<component name="CopyrightManager">
<settings default="" />
</component>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
... ...
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.mang.xdy.demo"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
repositories {
flatDir {
dirs 'libs'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile project(':xdy')
compile files('libs/pldroid-player-1.5.1.jar')
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.android.support:design:25.3.1'
compile 'com.squareup.picasso:picasso:2.3.2'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.rockerhieu.emojicon:library:1.3.1'
compile 'org.kymjs.kjframe:kjframe:2.6'
compile 'io.reactivex:rxjava:1.0.9'
compile 'io.reactivex:rxandroid:0.24.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'me.yokeyword:fragmentation:0.10.3'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'com.android.support:support-v4:25.3.1'
testCompile 'junit:junit:4.12'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'org.greenrobot:eventbus:3.0.0'
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.mang.xdy.demo"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
repositories {
flatDir {
dirs 'libs'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile project(':xdy')
compile files('libs/pldroid-player-1.5.1.jar')
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.android.support:design:25.3.1'
compile 'com.squareup.picasso:picasso:2.3.2'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.rockerhieu.emojicon:library:1.3.1'
compile 'org.kymjs.kjframe:kjframe:2.6'
compile 'io.reactivex:rxjava:1.0.9'
compile 'io.reactivex:rxandroid:0.24.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'me.yokeyword:fragmentation:0.10.3'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'com.android.support:support-v4:25.3.1'
testCompile 'junit:junit:4.12'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'org.greenrobot:eventbus:3.0.0'
}
... ...
package com.mang.xdy.demo;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.google.gson.Gson;
import com.mang.xdy.demo.activity.VideoPlayActivity;
import com.mang.xdy.demo.bean.JoinClass;
import com.mang.xdy.demo.bean.JoinClassBean;
import com.mang.xdy.demo.utils.ToastUtil;
import com.mang.xdy.utils.XdyLogUtil;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_home_classId)
EditText edtHomeClassId;
@BindView(R.id.edt_home_role)
EditText edtHomeRole;
@BindView(R.id.edt_home_serviceIp)
EditText edtHomeServiceIp;
@BindView(R.id.edt_home_userId)
EditText edtHomeUserId;
@BindView(R.id.btn_home_enter_class)
Button btnHomeEnterClass;
@BindView(R.id.btn_home_enter_publisher)
Button btn_home_enter_publisher;
@BindView(R.id.btn_home_enter_publisherAudio)
Button btn_home_enter_publisherAudio;
/*一进来就要初始化,让后再调 加入课堂*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher,R.id.btn_home_enter_publisherAudio})
public void onViewClicked(View view) {
if(TextUtils.isEmpty(joinClass())){
return;
}
ArrayList<String> arrayList=new ArrayList<>();
switch (view.getId()){
case R.id.btn_home_enter_class:
Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("normal");
intent.putStringArrayListExtra("init",arrayList);
startActivity(intent);
break;
case R.id.btn_home_enter_publisher:
Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("");
intents.putStringArrayListExtra("init",arrayList);
startActivity(intents);
break;
case R.id.btn_home_enter_publisherAudio:
// Intent intent_audio=new Intent(MainActivity.this, AudioPublisherActivity.class);
// intent_audio.putExtra("init",joinClass());
// startActivity(intent_audio);
break;
}
}
private String classId="";
private String userRole="";
private String serviceIp="";
private String userId="";
public boolean getLoginInfo(){
classId=edtHomeClassId.getText().toString();
userRole=edtHomeRole.getText().toString();
serviceIp=edtHomeServiceIp.getText().toString();
userId=edtHomeUserId.getText().toString();
if(TextUtils.isEmpty(classId)){
ToastUtil.showToast("课堂Id不能为空",this);
return false;
}
if(TextUtils.isEmpty(serviceIp)){
ToastUtil.showToast("服务器地址不能为空",this);
return false;
}
if(TextUtils.isEmpty(userRole)){
ToastUtil.showToast("角色不能为空",this);
return false;
}
if(TextUtils.isEmpty(userId)){
ToastUtil.showToast("用户id不能为空",this);
return false;
}
return true;
}
public String joinClass(){
if(getLoginInfo()) {
JoinClassBean joinClassBean = new JoinClassBean();
joinClassBean.setClassId(Integer.parseInt(classId));
joinClassBean.setUserRole(userRole);
joinClassBean.setPortal(serviceIp);
joinClassBean.setUserId(Integer.parseInt(userId));
joinClassBean.setUserName("");
String joinclass = new Gson().toJson(joinClassBean);
// XdyLogUtil.e("init 初始化", joinclass);
return joinclass;
}else{
return "";
}
}
}
package com.mang.xdy.demo;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.google.gson.Gson;
import com.mang.xdy.demo.activity.VideoPlayActivity;
import com.mang.xdy.demo.bean.JoinClassBean;
import com.mang.xdy.demo.utils.ToastUtil;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_home_classId)
EditText edtHomeClassId;
@BindView(R.id.edt_home_role)
EditText edtHomeRole;
@BindView(R.id.edt_home_serviceIp)
EditText edtHomeServiceIp;
@BindView(R.id.edt_home_userId)
EditText edtHomeUserId;
@BindView(R.id.btn_home_enter_class)
Button btnHomeEnterClass;
@BindView(R.id.btn_home_enter_publisher)
Button btn_home_enter_publisher;
/*一进来就要初始化,让后再调 加入课堂*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher})
public void onViewClicked(View view) {
if(TextUtils.isEmpty(joinClass())){
return;
}
ArrayList<String> arrayList=new ArrayList<>();
switch (view.getId()){
case R.id.btn_home_enter_class:
Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("normal");
intent.putStringArrayListExtra("init",arrayList);
startActivity(intent);
break;
case R.id.btn_home_enter_publisher:
Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("");
intents.putStringArrayListExtra("init",arrayList);
startActivity(intents);
break;
}
}
private String classId="";
private String userRole="";
private String serviceIp="";
private String userId="";
public boolean getLoginInfo(){
classId=edtHomeClassId.getText().toString();
userRole=edtHomeRole.getText().toString();
serviceIp=edtHomeServiceIp.getText().toString();
userId=edtHomeUserId.getText().toString();
if(TextUtils.isEmpty(classId)){
ToastUtil.showToast("课堂Id不能为空",this);
return false;
}
if(TextUtils.isEmpty(serviceIp)){
ToastUtil.showToast("服务器地址不能为空",this);
return false;
}
if(TextUtils.isEmpty(userRole)){
ToastUtil.showToast("角色不能为空",this);
return false;
}
if(TextUtils.isEmpty(userId)){
ToastUtil.showToast("用户id不能为空",this);
return false;
}
return true;
}
public String joinClass(){
if(getLoginInfo()) {
JoinClassBean joinClassBean = new JoinClassBean();
joinClassBean.setClassId(Integer.parseInt(classId));
joinClassBean.setUserRole(userRole);
joinClassBean.setPortal(serviceIp);
joinClassBean.setUserId(Integer.parseInt(userId));
joinClassBean.setUserName("");
String joinclass = new Gson().toJson(joinClassBean);
// XdyLogUtil.e("init 初始化", joinclass);
return joinclass;
}else{
return "";
}
}
}
... ...
package com.mang.xdy.demo.activity;
;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.PixelFormat;
import android.hardware.display.VirtualDisplay;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.google.gson.Gson;
import com.mang.xdy.bean.VideoPlayBean;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.common.Constants;
import com.mang.xdy.core.SPUtil;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter;
import com.mang.xdy.demo.bean.ErrorEntity;
import com.mang.xdy.demo.bean.InitClassSuccessEntity;
import com.mang.xdy.demo.bean.JoinClass;
import com.mang.xdy.demo.bean.ResponseEntity;
import com.mang.xdy.demo.bean.TimeEntity;
import com.mang.xdy.demo.bean.VideoOrAudioStopEntity;
import com.mang.xdy.demo.utils.JsonUtil;
import com.mang.xdy.demo.utils.ToastUtil;
import com.mang.xdy.demo.widget.dialog.LoginDialog;
import com.mang.xdy.demo.widget.view.NoScrollViewPager;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.utils.UIUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;
import com.pili.pldroid.player.widget.PLVideoView;
import com.videoengine.NTRenderer;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import static com.pili.pldroid.player.AVOptions.KEY_DELAY_OPTIMIZATION;
public class VideoPlayActivity extends AppCompatActivity implements ObserverListener, PLMediaPlayer.OnErrorListener, PLMediaPlayer.OnInfoListener,NoScrollViewPager.OnRplayTouchListener {
private final static String TAG = "VideoPlayActivity";
@BindView(R.id.img_playVideo_novideo)
ImageView img_playVideo_novideo;
@BindView(R.id.btn_videoPlay_exit)
Button btn_videoPlay_exit;
private String username = "";
private String userpwd = "";
private SimpleFragmentPagerAdapter pagerAdapter;
@BindView(R.id.viewpager)
NoScrollViewPager viewPager;
private TabLayout tabLayout;
@BindView(R.id.surfaceview_playVideo)
SurfaceView surfaceviewPlayVideo;
@BindView(R.id.fra_videoPlay_publish)
FrameLayout frameLayout_publish;
@BindView(R.id.btn_videoPlay_stopPublish)
Button btn_videoPlay_stopPublish;
/*推流*/
// @BindView(R.id.surfaceview_playVideo_text)
SurfaceView mSurfaceView ;
private String initClass = "";
private XdySdk xdySdk;
private LoginDialog mLoginDialog;
private ProgressDialog mProgressDialog;
@BindView(R.id.img_playVideo_replay)
PLVideoTextureView mVideoView;
private String playVideoOrAudioId="";
//视频模式还是音频模式
private boolean isVideoMode=true;
/*mcu断开或者网络原因为false*/
private boolean isDefaultExit=true;
private AlertDialog mErrorDialog;
private ACache aCache;
//TODO 默认回放
private boolean replay = false;
private Handler mmHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ResponseEntity responseEntity = (ResponseEntity) msg.obj;
switch (responseEntity.getType()) {
case Constants.CLASS_EXIT:
ToastUtil.showToast("退出课堂",VideoPlayActivity.this);
progressDialogDismiss();
exit();
break;
case Constants.ERROR_CODE:
handError(responseEntity.getType(), responseEntity.getParam());
break;
case Constants.CLASS_INIT_SUCCESS:
String login = responseEntity.getParam();
parseJoinClass(login, true);
ToastUtil.showToastshort("初始化课堂成功", VideoPlayActivity.this);
break;
case Constants.CLASS_JOIN_SUCCESS:
//加入课堂成功
progressDialogDismiss();
UIUtils.closeDialog(mLoginDialog);
ToastUtil.showToastshort("加入课堂成功", VideoPlayActivity.this);
String userJson = responseEntity.getParam();
SPUtil.putString(VideoPlayActivity.this, Constants.CLASS_JOIN_SUCCESS, userJson);
// JSONObject jsonObject = null;
// try {
// jsonObject = new JSONObject(userJson);
// replay = jsonObject.optBoolean("isRecordPlayBack");
// } catch (JSONException e) {
// e.printStackTrace();
// }
if(replay) {
initRecordSeek(userJson);
}
break;
case Constants.VIDEO_PLAY:
//播放视频
playVideoOrAudioId=responseEntity.getParam();
isVideoMode=true;
playVideo(responseEntity.getParam());
break;
case Constants.AUDIO_PLAY:
//播放音频
isVideoMode=false;
playVideoOrAudioId=responseEntity.getParam();
playAudio(responseEntity.getParam());
break;
case Constants.VIDEO_STOP:
//停止播放
case Constants.AUDIO_STOP:
//停止播放
stopPlay(responseEntity.getParam());
break;
case Constants.PLAY_SUCCESS:
//自定义消息 播放视频音频都通过这个来判断
img_playVideo_novideo.setVisibility(View.GONE);
break;
case Constants.CLASS_UPDATE_TIMER:
if(replay)
handleTime(responseEntity.getParam());
break;
case Constants.RECORD_PLAYBACK_UPDATE:
handleRecord(responseEntity.getParam());
break;
}
}
};
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //屏幕常亮
setContentView(R.layout.activity_video_play);
ButterKnife.bind(this);
aCache=ACache.get(this);
// XdySdk.init(this);
xdySdk = XdySdk.getXdyInstance();
xdySdk.add(this);
init();
progressDialogShow();
setTablayout();
}
public void init() {
ArrayList<String> arrayList=getIntent().getStringArrayListExtra("init");
if(arrayList!=null&&arrayList.size()>1){
initClass= arrayList.get(0);
if(TextUtils.isEmpty(arrayList.get(1))){
replay=true;
}else {
replay=false;
}
}
if(!replay){
mVideoView.setVisibility(View.GONE);
mMediaContainer.setVisibility(View.GONE);
// btn_videoPlay_exit.setVisibility(View.VISIBLE);
}else{
surfaceviewPlayVideo.setVisibility(View.GONE);
initReplay();
}
// initClass = getIntent().getStringExtra("init");
if(!replay){
xdySdk.api("init", initClass);
}else{
xdySdk.api("initRecordPlayback", initClass);
// xdySdk.api("startRecordPlayback", "");
}
currentTime=0;
btn_videoPlay_stopPublish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
xdySdk.api("stopPublishVideo", "");
}
});
btn_videoPlay_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mSurfaceView == null) {
mSurfaceView = NTRenderer.CreateRenderer(VideoPlayActivity.this, false);
}
btn_videoPlay_stopPublish.setVisibility(View.VISIBLE);
btn_videoPlay_exit.setVisibility(View.GONE);
btn_videoPlay_exit.setEnabled(false);
// mSurfaceView=new SurfaceView(VideoPlayActivity.this);
SurfaceHolder sh = mSurfaceView.getHolder();;
sh.setFormat(PixelFormat.TRANSPARENT);
mSurfaceView.setZOrderOnTop(true);
frameLayout_publish.addView(mSurfaceView);
xdySdk.api("publishVideo", "", mSurfaceView, VideoPlayActivity.this);
isVideoMode=true;
// mmHandler.post(new Runnable() {
// @Override
// public void run() {
// initSmall();
// }
// });
// xdySdk.api("leaveClass", "");
//
// xdySdk.remove(VideoPlayActivity.this);
// xdySdk.removeAll();
// UIUtils.closeDialog(mLoginDialog);
// VideoPlayActivity.super.onBackPressed();
// exit();
// String id="initRecordPlayback";
// String param="{\n" +
// " \"classId\": 391813551,\n" +
// " \"portal\": \"112.126.80.182:90\",\n" +
// " \"userRole\": \"normal\",\n" +
// " \"userName\": \"\",\n" +
// " \"userId\": 0\n" +
// "}";
// String ss=XdyStringUtils.stringToJson(param,true);
// xdySdk.api(id,ss);
// mHandler.postDelayed(new Runnable() {
// @Override
// public void run() {
// xdySdk.api("startRecordPlayback", "");
// }
// }, 200);
}
});
}
public void setTablayout() {
pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this,replay);
viewPager.setAdapter(pagerAdapter);
viewPager.setOnRplayTouchListener(this);
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
// tabLayout.setupWithViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager,false);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
}
//判断解析是否有密码
public void parseJoinClass(String rsponse, boolean isShowPwd) {
InitClassSuccessEntity initClassSuccessEntity = JsonUtil.parseJsonToBean(rsponse, InitClassSuccessEntity.class);
if (initClassSuccessEntity != null) {
if (initClassSuccessEntity.isPasswordRequired()) {
isShowPwd = true;
} else {
isShowPwd = false;
userpwd = "123321";
}
}
if (mLoginDialog == null) {
mLoginDialog = new LoginDialog(this, isShowPwd, null);
mLoginDialog.show();
progressDialogDismiss();
mLoginDialog.setCanceledOnTouchOutside(false);
final boolean finalIsShowPwd = isShowPwd;
mLoginDialog.setBtnClick(new View.OnClickListener() {
@Override
public void onClick(View view) {
String[] nameAndPwd = mLoginDialog.getNameAndPwd();
joinClass(nameAndPwd[0], nameAndPwd[1], finalIsShowPwd);
progressDialogShow();
}
});
} else if (mLoginDialog != null) {
UIUtils.closeDialog(mLoginDialog);
}
}
//加入课堂
public void joinClass(String rsponse, boolean isShowPwd) {
JoinClass joinClass = new JoinClass();
joinClass.setHasCamera(false);
joinClass.setHasMicrophone(false);
joinClass.setUserName(username);
if (!isShowPwd) {
joinClass.setPassword("123321");
} else {
joinClass.setPassword(userpwd);
}
String temp = new Gson().toJson(joinClass);
String jsonParmp = XdyStringUtils.stringToJson(temp, true);
XdyLogUtil.e("加入课堂", jsonParmp);
xdySdk.api("joinClass", jsonParmp);
}
//加入课堂
public void joinClass(String username, String userpwd, boolean isShowPwd) {
JoinClass joinClass = new JoinClass();
joinClass.setHasCamera(false);
joinClass.setHasMicrophone(false);
joinClass.setUserName(username);
if (!isShowPwd) {
joinClass.setPassword("123321");
} else {
joinClass.setPassword(userpwd);
}
String temp = new Gson().toJson(joinClass);
String jsonParmp = XdyStringUtils.stringToJson(temp, true);
XdyLogUtil.e("加入课堂", jsonParmp);
xdySdk.api("joinClass", jsonParmp);
}
/**
* 播放视频
*
* @param response
*/
public void playVideo(String response) {
progressDialogDismiss();
if(replay){
playRecord(response);
}else {
xdySdk.api("playVideo", response + "", surfaceviewPlayVideo, VideoPlayActivity.this);
// img_playVideo_novideo.setVisibility(View.GONE);
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
ToastUtil.showToastshort("视频播放初始化", VideoPlayActivity.this);
}
}
/**
* 播放音频
*
* @param response
*/
public void playAudio(String response) {
if(replay){
playRecord(response);
img_playVideo_novideo.setImageResource(R.mipmap.audio_mode);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}else {
xdySdk.api("playAudio", response, null, VideoPlayActivity.this);
img_playVideo_novideo.setImageResource(R.mipmap.audio_mode);
img_playVideo_novideo.setVisibility(View.VISIBLE);
ToastUtil.showToastshort("音频播放初始化", VideoPlayActivity.this);
}
}
@Override
public void onBackPressed() {
final AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("退出")
.setMessage("是否离开课堂")
.setNegativeButton("在看看", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//如果收到class_exit 就执行,退出界面
UIUtils.closeDialog(mLoginDialog);
exit();
// progressDialogShow();
}
})
.create();
alertDialog.show();
}
/**
* 错误处理
*
* @param errorId
* @param errorMsg
*/
public void handError(String errorId, String errorMsg) {
ErrorEntity errorEntity = JsonUtil.parseJsonToBean(errorMsg, ErrorEntity.class);
if (errorEntity == null) {
return;
}
switch (errorEntity.getCode() + "") {
case "100":
case "101":
case "102":
case "103":
case "104":
case "105":
case "106":
case "107":
case "200":
case "201":
case "202":
case "203":
case "204":
case "205":
case "206":
case "207":
case "208":
ToastUtil.showToastshort(errorEntity.getReson(), this);
exit();
break;
case "300":
case "301":
progressDialogDismiss();
break;
case "10000":
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
case "10001":
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
case "20000":
isDefaultExit=false;
showErrorDialog();
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
}
}
@Override
protected void onPause() {
super.onPause();
xdySdk.onPlayStop(playVideoOrAudioId);
if(isVideoMode){
stopVideo();
}else{
stopAudio();
}
xdySdk.api("pauseRecordPlayback","");
}
@Override
protected void onResume() {
super.onResume();
if (isVideoMode) {
playVideo(playVideoOrAudioId);
} else {
playAudio(playVideoOrAudioId);
}
xdySdk.api("startRecordPlayback","");
}
/**
* 错误情况退出
*/
public void exit() {
xdySdk.api("stopPublishVideo","");
xdySdk.api("leaveClass", "");
xdySdk.remove(this);
xdySdk.onPublisherStop();
if (mVideoView != null ){
mVideoView.stopPlayback();
}
UIUtils.closeDialog(mLoginDialog);
if(!replay) {
xdySdk.removeAll();
}
mmHandler.removeCallbacksAndMessages(null);
this.finish();
}
public void progressDialogDismiss() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
public void progressDialogShow() {
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(VideoPlayActivity.this, "", "加载中");
} else {
mProgressDialog.show();
}
}
/**
* 停止播放
*
* @param response
*/
public void stopPlay(String response) {
if(replay){
if(isVideoMode){
stopVideo();
}else{
stopAudio();
}
}else{
VideoOrAudioStopEntity entity = JsonUtil.parseJsonToBean(response, VideoOrAudioStopEntity.class);
if (entity != null) {
if (xdySdk.onPlayStop(entity.getMediaId() + "")) {
img_playVideo_novideo.setImageResource(R.mipmap.novideo);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}
}
}
}
public void showErrorDialog() {
if(isDefaultExit){
return;
}
if (mErrorDialog != null)
return;
mErrorDialog = new AlertDialog.Builder(this)
.setTitle("退出")
.setMessage("您设备的网络属于断开状态,请重新进入")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
exit();
}
})
.create();
mErrorDialog.setCanceledOnTouchOutside(false);
mErrorDialog.show();
}
@Override
public void observerUpData(String type, String parameter) {
XdyLogUtil.e(TAG + "observer:", Thread.currentThread().getId() + "type:"+type);
ResponseEntity responseEntity = new ResponseEntity(type, parameter);
Message message = Message.obtain();
message.obj = responseEntity;
mmHandler.sendMessage(message);
}
/******************************悬浮********************************/
/**
* 窗口管理者
*/
private WindowManager mWindowManager;
// desk capture
private int mScreenDensity;
private int sreenWindowWidth;
private int screenWindowHeight;
private VirtualDisplay mVirtualDisplay;
private MediaProjectionManager mMediaProjectionManager;
private MediaProjection mMediaProjection;
private SurfaceView bgSurfaceView;
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void createScreenEnvironment() {
sreenWindowWidth = mWindowManager.getDefaultDisplay().getWidth();
screenWindowHeight = mWindowManager.getDefaultDisplay().getHeight();
// if (sreenWindowWidth > 800) {
// if (screenResolution == SCREEN_RESOLUTION_STANDARD) {
// sreenWindowWidth = align(sreenWindowWidth / 2, 16);
// screenWindowHeight = align(screenWindowHeight / 2, 16);
// } else {
// sreenWindowWidth = align(sreenWindowWidth * 2 / 5, 16);
// screenWindowHeight = align(screenWindowHeight * 2 / 5, 16);
// }
// }
Log.i(TAG, "mWindowWidth : " + sreenWindowWidth + ",mWindowHeight : "
+ screenWindowHeight);
DisplayMetrics displayMetrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(displayMetrics);
mScreenDensity = displayMetrics.densityDpi;
// densityDpi mImageReader = ImageReader.newInstance(sreenWindowWidth,
// screenWindowHeight, 0x1, 2);
mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
public void initSmall(){
mWindowManager = (WindowManager) getSystemService(Service.WINDOW_SERVICE);
// if (pushType == PUSH_TYPE_CAMERA) {
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
// | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// PendingIntent contentIntent = PendingIntent.getActivity(this,
// 0, intent, 0);
//
// Intent bIntent = new Intent(this, BackgroudService.class);
// PendingIntent deleteIntent = PendingIntentnt.getService(this, 0,
// bIntent, 0);
//
//// notification = new Notification.Builder(this)
//// .setContentTitle("后台采集中。。").setAutoCancel(true)
//// .setDeleteIntent(deleteIntent)
//// .setContentIntent(contentIntent).build();
//
//// startForeground(android.os.Process.myPid(), notification);
bgSurfaceView = new SurfaceView(this);
bgSurfaceView.setZOrderMediaOverlay(true);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
1, 1, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
ImageView initPic = new ImageView(VideoPlayActivity.this);
initPic.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
initPic.setScaleType(ImageView.ScaleType.CENTER_CROP);
initPic.setImageResource(R.mipmap.no_video);
mWindowManager.addView(bgSurfaceView, layoutParams);
// xdySdk.api("publishVideo", "", bgSurfaceView, VideoPlayActivity.this);
// bgSurfaceView.getHolder().addCallback(this);
}
/*************************************** 回放***************************************************/
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mShowing;
private boolean mDragging;
private RelativeLayout mMediaControllerRight;
// @BindView(R.id.iv_operation_video)
// ImageView operationIcon;
// private PLMediaPlayer mMediaPlayer;
@BindView(R.id.fl_media)
FrameLayout mMediaContainer;
@BindView(R.id.iv_operation_play)
ImageButton mPauseButton;
@BindView(R.id.sb_live)
SeekBar mSeekBar;
@BindView(R.id.rl_operation_play)
RelativeLayout mPauseContainer;
private TextView mClassName;
@BindView(R.id.tv_end_time)
TextView mEndTime;
@BindView(R.id.tv_current_time)
TextView mCurrentTime;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FADE_OUT:
hideMediaContainer();
break;
case SHOW_PROGRESS:
setProgress();
if (!mDragging && mShowing) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000);
updatePausePlay();
}
break;
}
}
};
public void initReplay() {
mVideoView.setOnInfoListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener);
mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT);
AVOptions options = new AVOptions();
mSeekBar.setOnSeekBarChangeListener(mSeekListener);
// 解码方式:
// codec=AVOptions.MEDIA_CODEC_HW_DECODE,硬解
// codec=AVOptions.MEDIA_CODEC_SW_DECODE, 软解
// codec=AVOptions.MEDIA_CODEC_AUTO, 硬解优先,失败后自动切换到软解
// 默认值是:MEDIA_CODEC_SW_DECODE
options.setInteger(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_AUTO);
// 准备超时时间,包括创建资源、建立连接、请求码流等,单位是 ms
// 默认值是:无
options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
// 读取视频流超时时间,单位是 ms
// 默认值是:10 * 1000
options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);
// 当前播放的是否为在线直播,如果是,则底层会有一些播放优化
// 默认值是:0为关闭 1为是
if (!replay) {
options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1);
// 是否开启"延时优化",只在在线直播流中有效
// 默认值是:0
options.setInteger(KEY_DELAY_OPTIMIZATION, 1);
} else {
XdyLogUtil.i(TAG, "回放设置AVOptions.KEY_LIVE_STREAMING, 0");
options.setInteger(AVOptions.KEY_LIVE_STREAMING, 0);
}
// 默认的缓存大小,单位是 ms
// 默认值是:2000
options.setInteger(AVOptions.KEY_CACHE_BUFFER_DURATION, 300);
// 最大的缓存大小,单位是 ms
// 默认值是:4000
options.setInteger(AVOptions.KEY_MAX_CACHE_BUFFER_DURATION, 300);
// 是否自动启动播放,如果设置为 1,则在调用 `prepareAsync` 或者 `setVideoPath` 之后自动启动播放,无需调用 `start()`
// 默认值是:1
options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);
// 播放前最大探测流的字节数,单位是 byte
// 默认值是:128 * 1024
options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024);
options.setInteger(AVOptions.KEY_BUFFER_TIME, 300);
// 请在开始播放之前配置
mVideoView.setAVOptions(options);
mPauseContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开启或暂停回放
boolean pause = getRecordStatus();
pauseAndStart(!pause);
}
});
}
@Override
public boolean onError(PLMediaPlayer plMediaPlayer, int i) {
return false;
}
@Override
public boolean onInfo(PLMediaPlayer plMediaPlayer, int i, int i1) {
// boolean videoMode = mPresenter.isVideoMode();
// if (videoMode && PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START == i) {
//// initPic.setVisibility(View.INVISIBLE);
// }
return false;
}
private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(PLMediaPlayer plMediaPlayer) {
Log.d(TAG, "onSeekComplete !");
}
};
public void resetSeekBar() {
if (mSeekBar != null) {
setProgress();
}
}
public void setCurrentTime(int currentTime) {
this.currentTime = currentTime;
}
public void seekRecordPlay(long b) {
//TODO 清除以前的数据
// chatView.clearChatHistory();
// docView.clear();
EventBus.getDefault().post("doc");
EventBus.getDefault().post("chat");
seekRecordPlayback(b);
}
private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
mDragging = true;
showMediaContainer(TIME_OUT);
mHandler.removeMessages(SHOW_PROGRESS);
//停掉音视频
if (isVideoMode)
stopVideo();
else
stopAudio();
}
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (!fromuser)
return;
setCurrentTime(progress);
String time = generateTime(progress);
if (mCurrentTime != null)
mCurrentTime.setText(time);
}
public void onStopTrackingTouch(SeekBar bar) {
seekRecordPlay(bar.getProgress() == 0 ? 1 : bar.getProgress());
showMediaContainer(TIME_OUT);
mHandler.removeMessages(SHOW_PROGRESS);
mDragging = false;
mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000);
}
};
int TIME_OUT = 3600;
/**
* @param timeout 单位秒
*/
public void showMediaContainer(int timeout) {
if (!mShowing) {
if (mPauseContainer != null) {
mPauseContainer.requestLayout();
mPauseContainer.requestFocus();
}
mShowing = true;
}
updatePausePlay();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
mMediaContainer.setVisibility(View.VISIBLE);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT),
timeout);
}
}
private void setProgress() {
if (!mDragging) {
if (mEndTime != null)
mEndTime.setText(generateTime(seek));
if (mCurrentTime != null) {
mCurrentTime.setText(generateTime(currentTime));
}
if (mSeekBar != null) {
mSeekBar.setProgress(currentTime);
}
}
}
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
public void hideMediaContainer() {
if (!mDragging && mShowing) {
try {
mHandler.removeMessages(SHOW_PROGRESS);
mMediaContainer.setVisibility(View.GONE);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "MediaController already removed");
}
mShowing = false;
}
}
private boolean pause=true;
/**
* 退出标记
*/
private boolean quit;
private boolean isOver;
public void updatePausePlay() {
if (pause)
mPauseButton.setImageResource(R.mipmap.play);
else
mPauseButton.setImageResource(R.mipmap.stop);
}
private void handleRecord(String pa) {
try {
JSONObject jsonObject = new JSONObject(pa);
int status = jsonObject.optInt("status");
switch (status) {
case Constants.RECORD_READY:
pause = true;
isOver = false;
break;
case Constants.RECORD_PLAYING:
pause = false;
isOver = false;
pauseOrStartEverything();
break;
case Constants.RECORD_SEEK:
isOver = false;
pause = false;
// int keyFrameSeek = jsonObject.optInt("keyFrameSeekTime");
// mRootView.seek(keyFrameSeek);
break;
case Constants.RECORD_STOP:
pause = true;
// //停止后 录制回放要进行初始化
if (!quit) {//回放结束了
// isOver = true;
// if (currentTime < recordPlaybackMaxTime)
// currentTime++;
// xdySdk.api("initRecordPlayback", initClass);
// int classId = AccountUtils.getUser().getClassId();
// mModel.initRecordPlayback(classId, portal, userRole, userId);
// //停止视频
stopVideo();
currentTime = 0;
resetSeekBar();
// docView.clear();
// chatView.clearChatHistory();
// currentPlayAudio = null;
// currentPlayVideo = null;
EventBus.getDefault().post("doc");
EventBus.getDefault().post("chat");
}
break;
case Constants.RECORD_PAUSE:
isOver = false;
pause = true;
pauseOrStartEverything();
break;
}
updatePausePlay();
} catch (JSONException e) {
e.printStackTrace();
}
}
long seek=0;
int currentTime;
/**
* 录制回放初始化 seek长度等信息
*/
public void initRecordSeek(String response){
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
seek = jsonObject.optLong("recordPlaybackMaxTime");
} catch (JSONException e) {
e.printStackTrace();
}
// if (mVideoView.isPlaying()) {
// mVideoView.stopPlayback();
// }
// if (replay && seek > 0) {
// mVideoView.seekTo(seek * 1000);
setProgress();
//
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
xdySdk.api("startRecordPlayback", "");
}
}, 200);
mVideoView.start();
}
private void handleTime(String pa) {
try {
JSONObject jsonObject = new JSONObject(pa);
//防止时间超了
currentTime = jsonObject.optInt("classTimestamp");
boolean isRe = jsonObject.optBoolean("recordStatus");
} catch (JSONException e) {
e.printStackTrace();
}
setProgress();
}
// public void setProcess(){
// if (mEndTime != null)
// mEndTime.setText(generateTime(seek));
// if (mCurrentTime != null) {
// mCurrentTime.setText(generateTime(currentTime));
// }
// if (mSeekBar != null){
//// mSeekBar.setProgress(generateTime(currentTime));
// }
// }
public boolean getRecordStatus() {
return pause;
}
public void pauseOrStartEverything() {
boolean isPause = getRecordStatus();
if (isPause && mVideoView != null && mVideoView.isPlaying()) {
mVideoView.pause();
XdyLogUtil.i(TAG, "视频停止");
} else if (mVideoView != null) {
mVideoView.start();
XdyLogUtil.i(TAG, "视频开始");
}
}
/**
* 回放 播放 音视频
* @param response
*/
public void playRecord(String response){
String json_video= aCache.getAsString(response);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this VideoId");
return;
}
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
//回放不会出现Constants.PLAY_SUCCESS:
if(img_playVideo_novideo!=null)
img_playVideo_novideo.setVisibility(View.GONE);
if (mVideoView.isPlaying()) {
mVideoView.stopPlayback();
// mVideoView.pause();
}
mVideoView.setVideoPath(videoPlayBean.getReplay());
//TODO 这个地方需要调整进度的话
XdyLogUtil.e("播放精度哈哈哈哈哈",""+videoPlayBean.getSeek());
if (replay && videoPlayBean.getSeek() > 0) {
mVideoView.seekTo(videoPlayBean.getSeek() * 1000);
}
mVideoView.start();
XdyLogUtil.e("录制回放播放视频的了",""+videoPlayBean.getReplay());
}
}
public void stopVideo() {
mHandler.post(new Runnable() {
@Override
public void run() {
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}
});
if (isVideoMode && mVideoView != null && mVideoView.isPlaying())
mVideoView.stopPlayback();
}
public void stopAudio() {
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
img_playVideo_novideo.setVisibility(View.VISIBLE);
if (isVideoMode && mVideoView != null && mVideoView.isPlaying())
mVideoView.stopPlayback();
}
@Override
public void onClick() {
if (replay) {
if (mMediaContainer.getVisibility() == View.VISIBLE) {
hideMediaContainer();
} else {
showMediaContainer(TIME_OUT);
}
}
}
public void pauseAndStart(boolean b) {
if (b) {
pauseRecordPlayback();
} else {
startRecordPlayback();
}
}
public void pauseRecordPlayback() {
xdySdk.api("pauseRecordPlayback","");
}
public void startRecordPlayback() {
xdySdk.api("startRecordPlayback","");
}
public void seekRecordPlayback(long time) {
TimeEntity timeEntity=new TimeEntity(time);
xdySdk.api("seekRecordPlayback", new Gson().toJson(timeEntity));
}
}
package com.mang.xdy.demo.activity;
;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.PermissionChecker;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.mang.xdy.bean.VideoPlayBean;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.common.Constants;
import com.mang.xdy.core.SPUtil;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter;
import com.mang.xdy.demo.bean.ErrorEntity;
import com.mang.xdy.demo.bean.InitClassSuccessEntity;
import com.mang.xdy.demo.bean.JoinClass;
import com.mang.xdy.demo.bean.ResponseEntity;
import com.mang.xdy.demo.bean.TimeEntity;
import com.mang.xdy.demo.bean.VideoOrAudioStopEntity;
import com.mang.xdy.demo.utils.JsonUtil;
import com.mang.xdy.demo.utils.ToastUtil;
import com.mang.xdy.demo.widget.dialog.LoginDialog;
import com.mang.xdy.demo.widget.view.NoScrollViewPager;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.utils.UIUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;
import com.pili.pldroid.player.widget.PLVideoView;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import static com.pili.pldroid.player.AVOptions.KEY_DELAY_OPTIMIZATION;
public class VideoPlayActivity extends AppCompatActivity implements ObserverListener, PLMediaPlayer.OnErrorListener, PLMediaPlayer.OnInfoListener,NoScrollViewPager.OnRplayTouchListener {
private final static String TAG = "VideoPlayActivity";
@BindView(R.id.img_playVideo_novideo)
ImageView img_playVideo_novideo;
@BindView(R.id.img_videoPlay_start)
ImageView img_videoPlay_start;
private String username = "";
private String userpwd = "";
private SimpleFragmentPagerAdapter pagerAdapter;
@BindView(R.id.viewpager)
NoScrollViewPager viewPager;
private TabLayout tabLayout;
@BindView(R.id.surfaceview_playVideo)
SurfaceView surfaceviewPlayVideo;
@BindView(R.id.img_videoPlay_stopPublish)
ImageView btn_videoPlay_stopPublish;
@BindView(R.id.sur_plaVideo_publish)
SurfaceView surfaceView_publish;
private String initClass = "";
private XdySdk xdySdk;
private LoginDialog mLoginDialog;
private ProgressDialog mProgressDialog;
@BindView(R.id.img_playVideo_replay)
PLVideoTextureView mVideoView;
private String playVideoOrAudioId="";
//视频模式还是音频模式
private boolean isVideoMode=true;
/*mcu断开或者网络原因为false*/
private boolean isDefaultExit=true;
private AlertDialog mErrorDialog;
private ACache aCache;
//是否是回放状态,
private boolean replay = false;
SurfaceHolder sh;
@BindView(R.id.img_videoPlay_back)
ImageView mImageView_Back;
@BindView(R.id.tv_videoPlay_className)
TextView mTextView_ClassName;
/*课堂名字*/
private String className;
private Handler mmHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ResponseEntity responseEntity = (ResponseEntity) msg.obj;
switch (responseEntity.getType()) {
case Constants.CLASS_EXIT:
ToastUtil.showToast("退出课堂",VideoPlayActivity.this);
progressDialogDismiss();
exit();
break;
case Constants.ERROR_CODE:
handError(responseEntity.getType(), responseEntity.getParam());
break;
case Constants.CLASS_INIT_SUCCESS:
String login = responseEntity.getParam();
parseJoinClass(login, true);
ToastUtil.showToastshort("初始化课堂成功", VideoPlayActivity.this);
break;
case Constants.CLASS_JOIN_SUCCESS:
//加入课堂成功
progressDialogDismiss();
UIUtils.closeDialog(mLoginDialog);
ToastUtil.showToastshort("加入课堂成功", VideoPlayActivity.this);
String userJson = responseEntity.getParam();
SPUtil.putString(VideoPlayActivity.this, Constants.CLASS_JOIN_SUCCESS, userJson);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(userJson);
seek = jsonObject.optLong("recordPlaybackMaxTime");
className=jsonObject.optString("className");
} catch (JSONException e) {
e.printStackTrace();
}
if(!TextUtils.isEmpty(className)){
mTextView_ClassName.setText(className);
}
if(replay) {
initRecordSeek(userJson);
}
break;
case Constants.VIDEO_PLAY:
//播放视频
playVideoOrAudioId=responseEntity.getParam();
isVideoMode=true;
playVideo(responseEntity.getParam());
break;
case Constants.AUDIO_PLAY:
//播放音频
isVideoMode=false;
playVideoOrAudioId=responseEntity.getParam();
playAudio(responseEntity.getParam());
break;
case Constants.VIDEO_STOP:
//停止播放
case Constants.AUDIO_STOP:
//停止播放
stopPlay(responseEntity.getParam());
break;
case Constants.PLAY_SUCCESS:
//自定义消息 播放视频音频都通过这个来判断
img_playVideo_novideo.setVisibility(View.GONE);
break;
case Constants.CLASS_UPDATE_TIMER:
if(replay)
handleTime(responseEntity.getParam());
break;
case Constants.RECORD_PLAYBACK_UPDATE:
handleRecord(responseEntity.getParam());
break;
}
}
};
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //屏幕常亮
setContentView(R.layout.activity_video_play);
ButterKnife.bind(this);
aCache=ACache.get(this);
xdySdk = XdySdk.getXdyInstance();
xdySdk.add(this);
init();
progressDialogShow();
setTablayout();
}
public void init() {
ArrayList<String> arrayList=getIntent().getStringArrayListExtra("init");
if(arrayList!=null&&arrayList.size()>1){
initClass= arrayList.get(0);
if(TextUtils.isEmpty(arrayList.get(1))){
replay=true;
}else {
replay=false;
}
}
if(!replay){
mVideoView.setVisibility(View.GONE);
mMediaContainer.setVisibility(View.GONE);
img_videoPlay_start.setVisibility(View.VISIBLE);
// btn_videoPlay_stopPublish.setVisibility(View.VISIBLE);
}else{
surfaceviewPlayVideo.setVisibility(View.GONE);
initReplay();
}
if(!replay){
xdySdk.api("init", initClass);
}else{
xdySdk.api("initRecordPlayback", initClass);
}
currentTime=0;
btn_videoPlay_stopPublish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
xdySdk.api("stopPublishVideo", "");
img_videoPlay_start.setEnabled(true);
btn_videoPlay_stopPublish.setEnabled(false);
btn_videoPlay_stopPublish.setVisibility(View.GONE);
img_videoPlay_start.setVisibility(View.VISIBLE);
surfaceView_publish.setVisibility(View.GONE);
}
});
img_videoPlay_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btn_videoPlay_stopPublish.setVisibility(View.VISIBLE);
img_videoPlay_start.setVisibility(View.GONE);
surfaceView_publish.setVisibility(View.VISIBLE);
img_videoPlay_start.setEnabled(false);
btn_videoPlay_stopPublish.setEnabled(true);
sh = surfaceView_publish.getHolder();
surfaceView_publish.setZOrderMediaOverlay(true);
xdySdk.api("publishVideo", "", surfaceView_publish, VideoPlayActivity.this);
isVideoMode=true;
}
});
mImageView_Back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exit_dialog();
}
});
}
public void setTablayout() {
pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this,replay);
viewPager.setAdapter(pagerAdapter);
viewPager.setOnRplayTouchListener(this);
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager,false);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
}
//判断解析是否有密码
public void parseJoinClass(String rsponse, boolean isShowPwd) {
InitClassSuccessEntity initClassSuccessEntity = JsonUtil.parseJsonToBean(rsponse, InitClassSuccessEntity.class);
if (initClassSuccessEntity != null) {
if (initClassSuccessEntity.isPasswordRequired()) {
isShowPwd = true;
} else {
isShowPwd = false;
userpwd = "123321";
}
}
if (mLoginDialog == null) {
mLoginDialog = new LoginDialog(this, isShowPwd, null);
mLoginDialog.show();
progressDialogDismiss();
mLoginDialog.setCanceledOnTouchOutside(false);
final boolean finalIsShowPwd = isShowPwd;
mLoginDialog.setBtnClick(new View.OnClickListener() {
@Override
public void onClick(View view) {
String[] nameAndPwd = mLoginDialog.getNameAndPwd();
joinClass(nameAndPwd[0], nameAndPwd[1], finalIsShowPwd);
progressDialogShow();
}
});
} else if (mLoginDialog != null) {
UIUtils.closeDialog(mLoginDialog);
}
}
//加入课堂
public void joinClass(String username, String userpwd, boolean isShowPwd) {
JoinClass joinClass = new JoinClass();
joinClass.setHasCamera(false);
joinClass.setHasMicrophone(false);
joinClass.setUserName(username);
if (!isShowPwd) {
joinClass.setPassword("123321");
} else {
joinClass.setPassword(userpwd);
}
String temp = new Gson().toJson(joinClass);
String jsonParmp = XdyStringUtils.stringToJson(temp, true);
XdyLogUtil.e("加入课堂", jsonParmp);
xdySdk.api("joinClass", jsonParmp);
}
/**
* 播放视频
*
* @param response
*/
public void playVideo(String response) {
progressDialogDismiss();
if(replay){
playRecord(response);
}else {
if(!checkPermission()){
return;
}
xdySdk.api("playVideo", response + "", surfaceviewPlayVideo, VideoPlayActivity.this);
// img_playVideo_novideo.setVisibility(View.GONE);
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
ToastUtil.showToastshort("视频播放初始化", VideoPlayActivity.this);
}
}
/**
* 播放音频
*
* @param response
*/
public void playAudio(String response) {
if(replay){
playRecord(response);
img_playVideo_novideo.setImageResource(R.mipmap.audio_mode);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}else {
if(!checkPermission()){
return;
}
xdySdk.api("playAudio", response, null, VideoPlayActivity.this);
img_playVideo_novideo.setImageResource(R.mipmap.audio_mode);
img_playVideo_novideo.setVisibility(View.VISIBLE);
ToastUtil.showToastshort("音频播放初始化", VideoPlayActivity.this);
}
}
@Override
public void onBackPressed() {
exit_dialog();
}
public void exit_dialog(){
final AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("退出")
.setMessage("是否离开课堂")
.setNegativeButton("在看看", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//如果收到class_exit 就执行,退出界面
UIUtils.closeDialog(mLoginDialog);
exit();
}
})
.create();
alertDialog.show();
}
/**
* 错误处理
*
* @param errorId
* @param errorMsg
*/
public void handError(String errorId, String errorMsg) {
ErrorEntity errorEntity = JsonUtil.parseJsonToBean(errorMsg, ErrorEntity.class);
if (errorEntity == null) {
return;
}
switch (errorEntity.getCode() + "") {
case "100":
case "101":
case "102":
case "103":
case "104":
case "105":
case "106":
case "107":
case "200":
case "201":
case "202":
case "203":
case "204":
case "205":
case "206":
case "207":
case "208":
ToastUtil.showToastshort(errorEntity.getReson(), this);
exit();
break;
case "300":
case "301":
progressDialogDismiss();
break;
case "10000":
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
case "10001":
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
case "20000":
isDefaultExit=false;
showErrorDialog();
ToastUtil.showToastshort(errorEntity.getReson(), this);
break;
}
}
@Override
protected void onPause() {
super.onPause();
xdySdk.onPlayStop(playVideoOrAudioId);
if(isVideoMode){
stopVideo();
}else{
stopAudio();
}
if(replay) {
xdySdk.api("pauseRecordPlayback", "");
}
// xdySdk.onPublisherPause();
}
@Override
protected void onResume() {
super.onResume();
if (isVideoMode) {
playVideo(playVideoOrAudioId);
} else {
playAudio(playVideoOrAudioId);
}
if(replay) {
xdySdk.api("startRecordPlayback", "");
}
// xdySdk.onPublisherResume();
}
/**
* 错误情况退出
*/
public void exit() {
xdySdk.api("stopPublishVideo","");
xdySdk.api("leaveClass", "");
xdySdk.remove(this);
xdySdk.onPublisherStop();
if (mVideoView != null ){
mVideoView.stopPlayback();
}
UIUtils.closeDialog(mLoginDialog);
if(!replay) {
xdySdk.removeAll();
}
mmHandler.removeCallbacksAndMessages(null);
this.finish();
}
public void progressDialogDismiss() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
public void progressDialogShow() {
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(VideoPlayActivity.this, "", "加载中");
} else {
mProgressDialog.show();
}
}
/**
* 停止播放
*
* @param response
*/
public void stopPlay(String response) {
if(replay){
if(isVideoMode){
stopVideo();
}else{
stopAudio();
}
}else{
VideoOrAudioStopEntity entity = JsonUtil.parseJsonToBean(response, VideoOrAudioStopEntity.class);
if (entity != null) {
if (xdySdk.onPlayStop(entity.getMediaId() + "")) {
img_playVideo_novideo.setImageResource(R.mipmap.novideo);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}
}
}
}
public void showErrorDialog() {
if(isDefaultExit){
return;
}
if (mErrorDialog != null)
return;
mErrorDialog = new AlertDialog.Builder(this)
.setTitle("退出")
.setMessage("您设备的网络属于断开状态,请重新进入")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
exit();
}
})
.create();
mErrorDialog.setCanceledOnTouchOutside(false);
mErrorDialog.show();
}
private boolean isCameraCheckFirst=true;
private boolean isAudioCheckFirst=true;
private boolean checkPermission() {
// try {
// int pRecordAudio = PermissionChecker.checkCallingOrSelfPermission(this, "android.permission.RECORD_AUDIO");
// int pCamera = PermissionChecker.checkCallingOrSelfPermission(this, "android.permission.CAMERA");
// if(pRecordAudio != PackageManager.PERMISSION_GRANTED) {
// Log.e(TAG,"do not have AudioRecord permission, please check");
// Toast.makeText(this,"do not have AudioRecord permission, please check", Toast.LENGTH_LONG).show();
// if(isCameraCheckFirst){
// //settingPermission();
// isCameraCheckFirst=false;
// }
// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
// 1);
// return false;
// }
// if(pCamera != PackageManager.PERMISSION_GRANTED) {
// Log.e(TAG,"do not have CAMERA permission, please check");
// Toast.makeText(this,"do not have CAMERA permission, please check", Toast.LENGTH_LONG).show();
// if(isAudioCheckFirst){
// //settingPermission();
// isAudioCheckFirst=false;
// }
// return false;
//
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
return true;
}
@Override
public void observerUpData(String type, String parameter) {
XdyLogUtil.e(TAG + "observer:", Thread.currentThread().getId() + "type:"+type);
ResponseEntity responseEntity = new ResponseEntity(type, parameter);
Message message = Message.obtain();
message.obj = responseEntity;
mmHandler.sendMessage(message);
}
/*************************************** 回放***************************************************/
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mShowing;
private boolean mDragging;
private RelativeLayout mMediaControllerRight;
private boolean pause=true;
/**
* 退出标记
*/
private boolean quit;
private boolean isOver;
@BindView(R.id.fl_media)
FrameLayout mMediaContainer;
@BindView(R.id.iv_operation_play)
ImageButton mPauseButton;
@BindView(R.id.sb_live)
SeekBar mSeekBar;
@BindView(R.id.rl_operation_play)
RelativeLayout mPauseContainer;
private TextView mClassName;
@BindView(R.id.tv_end_time)
TextView mEndTime;
@BindView(R.id.tv_current_time)
TextView mCurrentTime;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FADE_OUT:
hideMediaContainer();
break;
case SHOW_PROGRESS:
setProgress();
if (!mDragging && mShowing) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000);
updatePausePlay();
}
break;
}
}
};
public void initReplay() {
mVideoView.setOnInfoListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener);
mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT);
AVOptions options = new AVOptions();
mSeekBar.setOnSeekBarChangeListener(mSeekListener);
// 解码方式:
// codec=AVOptions.MEDIA_CODEC_HW_DECODE,硬解
// codec=AVOptions.MEDIA_CODEC_SW_DECODE, 软解
// codec=AVOptions.MEDIA_CODEC_AUTO, 硬解优先,失败后自动切换到软解
// 默认值是:MEDIA_CODEC_SW_DECODE
options.setInteger(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_AUTO);
// 准备超时时间,包括创建资源、建立连接、请求码流等,单位是 ms
// 默认值是:无
options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
// 读取视频流超时时间,单位是 ms
// 默认值是:10 * 1000
options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);
// 当前播放的是否为在线直播,如果是,则底层会有一些播放优化
// 默认值是:0为关闭 1为是
if (!replay) {
options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1);
// 是否开启"延时优化",只在在线直播流中有效
// 默认值是:0
options.setInteger(KEY_DELAY_OPTIMIZATION, 1);
} else {
XdyLogUtil.i(TAG, "回放设置AVOptions.KEY_LIVE_STREAMING, 0");
options.setInteger(AVOptions.KEY_LIVE_STREAMING, 0);
}
// 默认的缓存大小,单位是 ms
// 默认值是:2000
options.setInteger(AVOptions.KEY_CACHE_BUFFER_DURATION, 300);
// 最大的缓存大小,单位是 ms
// 默认值是:4000
options.setInteger(AVOptions.KEY_MAX_CACHE_BUFFER_DURATION, 300);
// 是否自动启动播放,如果设置为 1,则在调用 `prepareAsync` 或者 `setVideoPath` 之后自动启动播放,无需调用 `start()`
// 默认值是:1
options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);
// 播放前最大探测流的字节数,单位是 byte
// 默认值是:128 * 1024
options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024);
options.setInteger(AVOptions.KEY_BUFFER_TIME, 300);
// 请在开始播放之前配置
mVideoView.setAVOptions(options);
mPauseContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开启或暂停回放
boolean pause = getRecordStatus();
pauseAndStart(!pause);
}
});
}
@Override
public boolean onError(PLMediaPlayer plMediaPlayer, int i) {
return false;
}
@Override
public boolean onInfo(PLMediaPlayer plMediaPlayer, int i, int i1) {
return false;
}
private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(PLMediaPlayer plMediaPlayer) {
Log.d(TAG, "onSeekComplete !");
}
};
public void resetSeekBar() {
if (mSeekBar != null) {
setProgress();
}
}
public void setCurrentTime(int currentTime) {
this.currentTime = currentTime;
}
public void seekRecordPlay(long b) {
//TODO 清除以前的数据
// chatView.clearChatHistory();
// docView.clear();
EventBus.getDefault().post("doc");
EventBus.getDefault().post("chat");
seekRecordPlayback(b);
}
private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
mDragging = true;
showMediaContainer(TIME_OUT);
mHandler.removeMessages(SHOW_PROGRESS);
//停掉音视频
if (isVideoMode)
stopVideo();
else
stopAudio();
}
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (!fromuser)
return;
setCurrentTime(progress);
String time = generateTime(progress);
if (mCurrentTime != null)
mCurrentTime.setText(time);
}
public void onStopTrackingTouch(SeekBar bar) {
seekRecordPlay(bar.getProgress() == 0 ? 1 : bar.getProgress());
showMediaContainer(TIME_OUT);
mHandler.removeMessages(SHOW_PROGRESS);
mDragging = false;
mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000);
}
};
int TIME_OUT = 3600;
/**
* @param timeout 单位秒
*/
public void showMediaContainer(int timeout) {
if (!mShowing) {
if (mPauseContainer != null) {
mPauseContainer.requestLayout();
mPauseContainer.requestFocus();
}
mShowing = true;
}
updatePausePlay();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
mMediaContainer.setVisibility(View.VISIBLE);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT),
timeout);
}
}
private void setProgress() {
if (!mDragging) {
if (mEndTime != null)
mEndTime.setText(generateTime(seek));
if (mCurrentTime != null) {
mCurrentTime.setText(generateTime(currentTime));
}
if (mSeekBar != null) {
mSeekBar.setProgress(currentTime);
}
}
}
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
public void hideMediaContainer() {
if (!mDragging && mShowing) {
try {
mHandler.removeMessages(SHOW_PROGRESS);
mMediaContainer.setVisibility(View.GONE);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "MediaController already removed");
}
mShowing = false;
}
}
public void updatePausePlay() {
if (pause)
mPauseButton.setImageResource(R.mipmap.play);
else
mPauseButton.setImageResource(R.mipmap.stop);
}
private void handleRecord(String pa) {
try {
JSONObject jsonObject = new JSONObject(pa);
int status = jsonObject.optInt("status");
switch (status) {
case Constants.RECORD_READY:
pause = true;
isOver = false;
break;
case Constants.RECORD_PLAYING:
pause = false;
isOver = false;
pauseOrStartEverything();
break;
case Constants.RECORD_SEEK:
isOver = false;
pause = false;
break;
case Constants.RECORD_STOP:
pause = true;
// //停止后 录制回放要进行初始化
if (!quit) {//回放结束了
// //停止视频
stopVideo();
currentTime = 0;
resetSeekBar();
EventBus.getDefault().post("doc");
EventBus.getDefault().post("chat");
}
break;
case Constants.RECORD_PAUSE:
isOver = false;
pause = true;
pauseOrStartEverything();
break;
}
updatePausePlay();
} catch (JSONException e) {
e.printStackTrace();
}
}
long seek=0;
int currentTime;
/**
* 录制回放初始化 seek长度等信息
*/
public void initRecordSeek(String response){
setProgress();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
xdySdk.api("startRecordPlayback", "");
}
}, 200);
mVideoView.start();
}
private void handleTime(String pa) {
try {
JSONObject jsonObject = new JSONObject(pa);
//防止时间超了
currentTime = jsonObject.optInt("classTimestamp");
boolean isRe = jsonObject.optBoolean("recordStatus");
} catch (JSONException e) {
e.printStackTrace();
}
setProgress();
}
public boolean getRecordStatus() {
return pause;
}
public void pauseOrStartEverything() {
boolean isPause = getRecordStatus();
if (isPause && mVideoView != null && mVideoView.isPlaying()) {
mVideoView.pause();
XdyLogUtil.i(TAG, "视频停止");
} else if (mVideoView != null) {
mVideoView.start();
XdyLogUtil.i(TAG, "视频开始");
}
}
/**
* 回放 播放 音视频
* @param response
*/
public void playRecord(String response){
String json_video= aCache.getAsString(response);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this VideoId");
return;
}
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
//回放不会出现Constants.PLAY_SUCCESS:
if(img_playVideo_novideo!=null)
img_playVideo_novideo.setVisibility(View.GONE);
if (mVideoView.isPlaying()) {
mVideoView.stopPlayback();
}
mVideoView.setVideoPath(videoPlayBean.getReplay());
if (replay && videoPlayBean.getSeek() > 0) {
mVideoView.seekTo(videoPlayBean.getSeek() * 1000);
}
mVideoView.start();
}
}
public void stopVideo() {
mHandler.post(new Runnable() {
@Override
public void run() {
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
img_playVideo_novideo.setVisibility(View.VISIBLE);
}
});
if (isVideoMode && mVideoView != null && mVideoView.isPlaying())
mVideoView.stopPlayback();
}
public void stopAudio() {
img_playVideo_novideo.setImageResource(R.mipmap.no_video);
img_playVideo_novideo.setVisibility(View.VISIBLE);
if (isVideoMode && mVideoView != null && mVideoView.isPlaying())
mVideoView.stopPlayback();
}
@Override
public void onClick() {
if (replay) {
if (mMediaContainer.getVisibility() == View.VISIBLE) {
hideMediaContainer();
} else {
showMediaContainer(TIME_OUT);
}
}
}
public void pauseAndStart(boolean b) {
if (b) {
pauseRecordPlayback();
} else {
startRecordPlayback();
}
}
public void pauseRecordPlayback() {
xdySdk.api("pauseRecordPlayback","");
}
public void startRecordPlayback() {
xdySdk.api("startRecordPlayback","");
}
public void seekRecordPlayback(long time) {
TimeEntity timeEntity=new TimeEntity(time);
xdySdk.api("seekRecordPlayback", new Gson().toJson(timeEntity));
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="课堂Id"
/>
<EditText
android:id="@+id/edt_home_classId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入课堂号"
android:text="391813551"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="角色"/>
<EditText
android:id="@+id/edt_home_role"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="normal"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="服务器地址"
/>
<EditText
android:id="@+id/edt_home_serviceIp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="112.126.80.182:90"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户id"
/>
<EditText
android:id="@+id/edt_home_userId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0"
/>
<Button
android:id="@+id/btn_home_enter_class"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="进入课堂"
/>
<Button
android:id="@+id/btn_home_enter_publisher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="录制回放"
/>
<Button
android:id="@+id/btn_home_enter_publisherAudio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="推音频"
android:visibility="gone"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="课堂Id"
/>
<EditText
android:id="@+id/edt_home_classId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入课堂号"
android:text="1332699420"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="角色"/>
<EditText
android:id="@+id/edt_home_role"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="normal"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="服务器地址"
/>
<EditText
android:id="@+id/edt_home_serviceIp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="112.126.80.182:90"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户id"
/>
<EditText
android:id="@+id/edt_home_userId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0"
/>
<Button
android:id="@+id/btn_home_enter_class"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="进入课堂"
/>
<Button
android:id="@+id/btn_home_enter_publisher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="录制回放"
/>
</LinearLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_video_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.activity.VideoPlayActivity">
<FrameLayout
android:id="@+id/fl_videoview_container"
android:layout_width="match_parent"
android:layout_height="1dp"
android:visibility="gone">
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/ui_DIMEN_500.0PX">
<com.pili.pldroid.player.widget.PLVideoTextureView
android:id="@+id/img_playVideo_replay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<SurfaceView
android:id="@+id/surfaceview_playVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!--<FrameLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent">-->
<ImageView
android:id="@+id/img_playVideo_novideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/novideo"
/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/fra_videoPlay_publish"
android:layout_width="150dp"
android:layout_gravity="right|bottom"
android:layout_height="100dp">
<Button
android:id="@+id/btn_videoPlay_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始推流"
android:visibility="gone"
/>
</FrameLayout>
</FrameLayout>
</RelativeLayout>
<SurfaceView
android:id="@+id/surfaceview_playVideo_text"
android:layout_width="150dp"
android:layout_height="200dp"
android:visibility="gone"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_videoPlay_stopPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="结束按钮"
android:visibility="gone"
/>
</FrameLayout>
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<!--</FrameLayout>-->
<com.mang.xdy.demo.widget.view.NoScrollViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white" />
<FrameLayout
android:id="@+id/fl_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<include
layout="@layout/home_media_controller"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_video_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.activity.VideoPlayActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/ui_DIMEN_500.0PX">
<com.pili.pldroid.player.widget.PLVideoTextureView
android:id="@+id/img_playVideo_replay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<SurfaceView
android:id="@+id/surfaceview_playVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_playVideo_novideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/novideo"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:id="@+id/linearLayout">
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_below="@+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<RelativeLayout
android:id="@+id/avg_videoPlay_back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingLeft="@dimen/ui_DIMEN_20.0PX"
android:paddingRight="@dimen/ui_DIMEN_20.0PX">
<ImageView
android:id="@+id/img_videoPlay_back"
android:layout_width="wrap_content"
android:layout_height="@dimen/ui_titlebar_height"
android:paddingRight="20dp"
android:paddingLeft="15dp"
android:src="@mipmap/back"/>
<TextView
android:id="@+id/tv_videoPlay_className"
style="@style/ui_wrapTvBaseStyle"
android:layout_height="@dimen/ui_titlebar_height"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textColor="@color/white"
tools:text="hahaha"
android:textSize="@dimen/ui_DIMEN_34.0PX"/>
</RelativeLayout>
<SurfaceView
android:id="@+id/sur_plaVideo_publish"
android:layout_width="120dp"
android:layout_height="150dp"
android:visibility="gone"
tools:visibility="visible"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<ImageView
android:id="@+id/img_videoPlay_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="25dp"
android:layout_marginBottom="20dp"
android:visibility="gone"
tools:visibility="visible"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@mipmap/camerap_normal2x"
/>
<ImageView
android:id="@+id/img_videoPlay_stopPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/sur_plaVideo_publish"
android:enabled="false"
android:background="@mipmap/hangup_normal2x"
android:visibility="gone"
android:layout_marginRight="25dp"
android:layout_marginBottom="20dp"
tools:visibility="visible"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</RelativeLayout>
<SurfaceView
android:id="@+id/surfaceview_playVideo_text"
android:layout_width="150dp"
android:layout_height="200dp"
android:visibility="gone"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
</FrameLayout>
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.mang.xdy.demo.widget.view.NoScrollViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white" />
<FrameLayout
android:id="@+id/fl_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<include
layout="@layout/home_media_controller"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
</LinearLayout>
... ...
... ... @@ -41,8 +41,6 @@
android:gravity="end"
tools:text="12:00:12"/>
<TextView
android:id="@+id/tv_end_time"
style="@style/ui_wrapTvBaseStyle"
... ... @@ -51,7 +49,6 @@
android:textColor="@color/white"
tools:text="12:00"/>
<SeekBar
android:id="@+id/sb_live"
style="@style/home_seek_bar"
... ...
//package com.mang.xdy.api;
//
//import android.content.Context;
//
//
//import com.mang.xdy.common.Constants;
//import com.mang.xdy.core.XdyCore;
//import com.mang.xdy.utils.XdyLogUtil;
//
///**
// * 对外调用的接口
// * Created by abao on 2017/3/31.
// */
//public class XdyInterface {
// /**
// * 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件
// */
// private static XdyCore mXdyCore;
// private static XdyInterface mXdyInterface;
//
// /**
// * 对外提供的异步消息接收接口(可以多个吗?)
// */
// public interface OnXdyAsyncMessageLitener{
// /**
// *
// * @param type 接收到的数据类型
// * @param response 返回数据
// */
// void onXdyAsyncMessageReceiver(String type,String response);
// }
// private static OnXdyAsyncMessageLitener mOnXdyAsyncMessageLitener;
//
// /**
// * 设置监听
// */
// public void setOnXdyAsyncMessageLitener(OnXdyAsyncMessageLitener onXdyAsyncMessageLitener){
// mOnXdyAsyncMessageLitener=onXdyAsyncMessageLitener;
// }
// private XdyInterface(){}
// /**
// * 初始化
// * @param context
// */
// public static void init(Context context){
// if(context==null){
// throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL);
// }
// mXdyCore = XdyCore.getInstance(context);
// mXdyCore.setXdyAsyncMessageListener(new XdyCore.OnXdyAsyncMessageListener() {
// @Override
// public void getSdyAsyncMessageListener(String id, String parameter) {
// XdyLogUtil.e(null,""+"xdy init success");
// if(mOnXdyAsyncMessageLitener!=null){
// mOnXdyAsyncMessageLitener.onXdyAsyncMessageReceiver(id,parameter);
// }
// }
// });
// }
//
// /**
// * 接收用户传递进来的参数
// */
// public static void setAsyncApi(String type,String argument){
// judgeCore();
// mXdyCore.native2js(type,argument);
// }
// /*判断是否被初始化*/
// public static void judgeCore(){
// if(mXdyCore==null){
// throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT);
// }
//
// }
// public static XdyInterface getXdyInstance(){
// if(mXdyInterface==null){
// synchronized (XdyInterface.class){
// mXdyInterface=new XdyInterface();
// }
// }
// return mXdyInterface;
// }
//}
package com.mang.xdy.cache;
/**
* Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.Context;
import android.graphics.Bitmap;
... ...
... ... @@ -196,7 +196,7 @@ public interface Constants {
/**
* 断线重连时间间隔
*/
long TIME_NET_ERROR_RECONNECTION=6000;
long TIME_NET_ERROR_RECONNECTION=5000;
/**********************************以下实现为自定义code 先定义后实现*********************************************************************/
/**
... ...
... ... @@ -157,6 +157,7 @@ public class XdyPlayerCore {
libPlayer.SmartPlayerClose(playerHandle);
playerHandle = 0;
}
isPlaying = false;
}
/**
* 停止播放,重置正在播放标识
... ...
package com.mang.xdy.core;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import com.eventhandle.SmartEventCallback;
import com.google.gson.Gson;
import com.mang.xdy.bean.AudioPlayBean;
import com.mang.xdy.bean.ErrorCodeEntity;
import com.mang.xdy.bean.GetPublishPathReceiveBean;
import com.mang.xdy.bean.PublisherSuccessEntity;
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.listener.ObserverListener;
import com.mang.xdy.listener.SubjectListener;
import com.mang.xdy.message.MsgManage;
import com.mang.xdy.utils.JsonUtil;
import com.mang.xdy.utils.NetWorkUtils;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
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 implements SubjectListener{
/**
* 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件
*/
private static XdyJsCore mXdyJsCore;
private static XdySdk mXdySdk;
private static Context mContext;
private XdyPlayerCore mXdyPlayerCore;
private XdyPublisherCore mXdyPublisherCore;
/*消息管理*/
private static MsgManage mMsgManage;
public static String TAG="xdysdk";
private String currentPlayId="";
/*缓存管理*/
private static ACache aCache;
//TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏)
private SurfaceView mSurfaceView_Publish;
private Activity mActivity;
/*是否正在推流,mcu自动断开的时候使用,推流成功后才表示正在使用*/
private boolean isPublisher =false;
// /*Audio 推送中,resume需要使用*/
private boolean isPublisherAudio=false;
/*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/
private boolean isReconnection=false;
/*是否进行录制回放*/
private boolean isRecordPlayBack=false;
/*观察者集合*/
private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>();
/*推流地址*/
private String publish_url="";
@Override
public void add(ObserverListener observerListener) {
observerListenerList.add(observerListener);
}
@Override
public void notifyObserver(String type, String parameter) {
handleData(type,parameter);
XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter);
}
@Override
public void remove(ObserverListener observerListener) {
if(observerListenerList!=null){
if(observerListenerList.contains(observerListener)) {
observerListenerList.remove(observerListener);
}
}
}
/**
* 对外提供的异步消息接收接口)
*/
public interface OnXdyAsyncMessageLitener{
/**
*
* @param type 接收到的数据类型
* @param response 返回数据
*/
void onXdyAsyncMessageReceiver(String type, String response);
}
private OnXdyAsyncMessageLitener mOnXdyAsyncMessageLitener;
/**
* 设置监听
*/
public void setOnXdyAsyncMessageLitener(OnXdyAsyncMessageLitener onXdyAsyncMessageLitener){
judgeCore();
mOnXdyAsyncMessageLitener=onXdyAsyncMessageLitener;
}
private XdySdk(){}
private static Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.LEAVE_CLASS_CODE){
if(!NetWorkUtils.isNetworkConnected(mContext)) {
if (mXdySdk != null) {
mXdySdk.onPublisherStop();
handler.removeCallbacksAndMessages(null);
}
}
}
}
};
/**
* 初始化
* @param context
*/
public static void init(final Context context){
if(context==null){
throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL);
}
aCache=ACache.get(context);
mContext=context;
mXdyJsCore = XdyJsCore.getInstance(context);
mMsgManage=MsgManage.getErrorMsgInstance();
}
/**
* 接收用户传递进来的参数(两个String 的参数都在这里处理)
* @param type 类型
* @param argument 参数
*/
public void api(final String type, final String argument){
judgeCore();
//再次停止播放器
switch (type){
case "stopPublishAudio":
//停止推送音频
case "stopPublishVideo":
//停止推流video(关闭视频:根据api)
onPublisherStop();
break;
case "stopAudio":
//停止播放audio()
case"stopVideo":
//停止播放video( 停止播放:根据api)
onPlayDestroy();
break;
}
handler.post(new Runnable() {
@Override
public void run() {
mXdyJsCore.native2js(type, argument);
}
});
}
/**
*
* @param type
* @param
* @param surfaceView
* @param activity
* @param
*
*/
public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) {
judgeString(type);
switch (type) {
case Constants.PLAY_AUDIO:
//播放音频
/**
* 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
*
*/
String json_audio= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_audio)){
//TODO/给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Audio Can not find this AudioId");
return;
}
currentPlayId=mediaId;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class);
if(audioPlayBean!=null) {
String play_url_audio="";
if(isRecordPlayBack){
play_url_audio=audioPlayBean.getReplay();
}else{
play_url_audio=audioPlayBean.getRtmpUrl() ;
if(mXdyPlayerCore==null) {
mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_audio, activity);
}else{
mXdyPlayerCore.onStopPlay();
}
mXdyPlayerCore.playAudio(play_url_audio, new EventHande_Play());
}
}else{
XdyLogUtil.e(TAG,"Can not get play Audio response");
}
break;
case Constants.PLAY_VIDEO:
//播放视频
/**
* 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
*
*/
String json_video= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this VideoId");
return;
}
currentPlayId=mediaId;
VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
String play_url_video="";
if(isRecordPlayBack){
play_url_video=videoPlayBean.getReplay();
}else{
play_url_video=videoPlayBean.getRtmpUrl();
if(mXdyPlayerCore==null) {
mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_video, activity);
}else{
//重复播放时候
mXdyPlayerCore.onStopPlay();
}
mXdyPlayerCore.playVideo(play_url_video, surfaceView,new EventHande_Play());
}
}else{
//统一提示推流错误
XdyLogUtil.e(TAG,"Can not get play Video response");
}
break;
case Constants.PUBLISH_VIDEO:
//打开推流视频
/**
* 用户发起这个推流的请求的时候,
* 1,去获取推流地址
* 2,判断地址时候有用,有用的话打开播放器,开启推流的过程
* 3,推流成功告知后台,和用户
*
*/
getPublishPathVideo();
mSurfaceView_Publish=surfaceView;
mActivity=activity;
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
getPublishPathAudio();
// mSurfaceView=surfaceView;
mActivity=activity;
break;
}
}
/*判断是否被初始化*/
private void judgeCore(){
if(mXdyJsCore==null){
throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT);
}
}
/*判断type是否为空*/
private void judgeString(String type){
if(TextUtils.isEmpty(type)){
XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL);
}
}
/*判断是否是合法的url*/
protected void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
public static XdySdk getXdyInstance(){
if(mXdySdk ==null){
synchronized (XdySdk.class){
mXdySdk =new XdySdk();
}
}
return mXdySdk;
}
/**
*core获取到的数据处理
* @param type
* @param response
*/
private void handleData(String type,String response){
//开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url
/*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和
audio
plublisher Video
publisher Audio
*/
switch (type) {
case Constants.CLASS_JOIN_SUCCESS:
//判断是否是录制回放,调整播流地址
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack");
} catch (JSONException e) {
e.printStackTrace();
}
handleListener(type,response);
break;
case Constants.VIDEO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
// String publishPath=XdyStringUtils.stringToJson(response);
String publishPath=response;
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null) {
//可以推流了
if (getPublishPathReceiveBean.getCode() == 0) {
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路
String video_url = getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url);
//判断
if (mSurfaceView_Publish == null) {
//todo 输出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW);
}
if (mActivity == null) {
//TODo 给出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY);
}
if (mXdyPublisherCore == null) {
mXdyPublisherCore = new XdyPublisherCore(1, 1, mActivity);
}
publish_url=video_url;
isPublisher =true;
isPublisherAudio=false;
mXdyPublisherCore.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish());
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
setPublishSendSuccessVideo(video_url);
}else{
mMsgManage.getPublishVideoPathError();
}
}else{
//给出提示
mMsgManage.getPublishVideoPathError();
}
break;
case Constants.AUDIO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
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();
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
aCache.put(Constants.GET_VIDEO_PUBLISH_PATH,audio_url);
//判断
// if (mSurfaceView==null){
// //todo 输出提示
// XdyLogUtil.e(TAG,"surfaceView is null");
// return;
// }
if(mActivity==null){
//TODo 给出提示
XdyLogUtil.e(TAG,"activity is null");
return;
}
if(mXdyPublisherCore==null)
mXdyPublisherCore=new XdyPublisherCore(1,0,mActivity);
mXdyPublisherCore.publisherAudio(audio_url,new EventHande_Publish());
publish_url=audio_url;
isPublisher =true;
isPublisherAudio=true;
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessAudio(audio_url);
}else{
//给出提示
mMsgManage.getPublishVideoPathError();
}
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
//接收后台是否接收到推流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.VIDEO_PUBLISH_RESULT:
//接收发送推流地址给后台返回的信息
String publishReplay=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay));
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class);
if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.VIDEO_PLAY:
//获取推流的地址,需要保存起来
//解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况
String video=response;
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class);
if(videoPlayBean!=null) {
if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) {
aCache.put(videoPlayBean.getMediaId() + "", video);
handleListener(type, videoPlayBean.getMediaId() + "");
}
}
break;
case Constants.AUDIO_PLAY:
String audio=response;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class);
if(audioPlayBean!=null){
if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) {
aCache.put(audioPlayBean.getMediaId() + "", audio);
handleListener(type, audioPlayBean.getMediaId() + "");
}
}
break;
case Constants.ERROR_CODE:
ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class);
if(errorCodeEntity!=null){
if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){
/**
* 方案 一 1,正在直播的时候mcu无故断开,需要重新连接
* 2,class exit 时候主动课堂停止,停止推流
* 利用mcu的生命周期,加入课堂成功后去请求数据
*/
// 方案 二 mcu 断开,页面也断开,用户需要手动重新调用
if(isPublisher) {
if(!NetWorkUtils.isNetworkConnected(mContext)){
//todo判断是否有网络,没有网络的话就让其退出
// TOdo 延迟10秒,
// onPublisherStop();
handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION);
}
isReconnection=true;
}
}
}
handleListener(type,response);
break;
case Constants.CLASS_EXIT:
/**
* 处理正在推流视频,课堂退出的情况,(用户操作退出界面)
* 此时,停止推流,清除surfaceview Activtity 数据,url数据
*/
if(isPublisher){
onPublisherStop();
}
handleListener(type,response);
break;
default:{
handleListener(type,response);
}
}
}
/**
* 处理所有向外发送的接口数据
* @param type
* @param parameter
*/
private void handleListener(String type,String parameter){
if(mOnXdyAsyncMessageLitener!=null){
mOnXdyAsyncMessageLitener.onXdyAsyncMessageReceiver(type,parameter);
}
for(ObserverListener o:observerListenerList){
o.observerUpData(type,parameter);
}
}
/**
* 销毁播放音视频
* @param id
* @return
*/
public boolean onPlayStop(String id){
if(currentPlayId.equals(id)) {
if (mXdyPlayerCore != null) {
mXdyPlayerCore.onStopPlay();
// mXdyPlayerCore = null;
}
return true;
}
return false;
}
/**
* 退出时清除信息(重置js监听)
*/
public void removeAll(){
if(mXdyPlayerCore!=null) {
mXdyPlayerCore.onPause();
}
if(mXdyJsCore!=null&&!isRecordPlayBack) {
mXdyJsCore.init(mContext);
}
}
/**
* 结束时调用
*/
public void onPlayDestroy(){
if (mXdyPlayerCore != null) {
mXdyPlayerCore.onStopPlay();
mXdyPlayerCore = null;
}
}
/**
* 推送视频音频停止方法(最后调用的方法)
* @deprecated daniu sdk handle best
*/
public void onPublisherStop(){
if(mXdyPublisherCore!=null){
mXdyPublisherCore.onStopPublisher();
mXdyPublisherCore=null;
}
//如果正在推流,msurfaceView ,mActivity不清空
if(!isPublisher) {
if (mSurfaceView_Publish != null) {
mSurfaceView_Publish = null;
}
if (mActivity != null) {
mActivity = null;
}
}
isPublisher =false;
isReconnection=false;
isPublisherAudio=false;
}
/**
* onPause 方法时走的周期
*/
public void onPublisherPause(){
if(mXdyPublisherCore!=null){
mXdyPublisherCore.onPausePublisher();
}
}
/**
* onResume 调用,目前是空方法
* TODO 只有一个boolean
* 开始isPublish 为false
* 开始推流初始化后onresume 就是开始
* @deprecated 大牛 sdk处理的更好
*/
public void onPublisherResume(){
if(!isPublisher){
return;
}
if(mXdyPublisherCore!=null) {
mXdyPublisherCore.onResumePublisher();
if (!TextUtils.isEmpty(publish_url)) {
if(!isPublisherAudio){
mXdyPublisherCore.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish());
}else{
mXdyPublisherCore.publisherAudio(publish_url,new EventHande_Publish());
}
}
}
}
class EventHande_Play implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
class EventHande_Publish implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
/**
* 向后台发送推流数据(Auido)成功信息
* @param url
*/
protected static void setPublishSendSuccessAudio(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp);
}
}
/**
* 向后台发送推流(Video)成功的信息
* @param url
*/
protected static void setPublishSendSuccessVideo(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+"");
XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp);
}
}
}
package com.mang.xdy.core;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import com.eventhandle.SmartEventCallback;
import com.google.gson.Gson;
import com.mang.xdy.bean.AudioPlayBean;
import com.mang.xdy.bean.ErrorCodeEntity;
import com.mang.xdy.bean.GetPublishPathReceiveBean;
import com.mang.xdy.bean.PublisherSuccessEntity;
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.listener.ObserverListener;
import com.mang.xdy.listener.SubjectListener;
import com.mang.xdy.message.MsgManage;
import com.mang.xdy.utils.JsonUtil;
import com.mang.xdy.utils.NetWorkUtils;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
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 implements SubjectListener{
/**
* 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件
*/
private static XdyJsCore mXdyJsCore;
private static XdySdk mXdySdk;
private static Context mContext;
private XdyPlayerCore mXdyPlayerCore;
private XdyPublisherCore mXdyPublisherCore;
/*消息管理*/
private static MsgManage mMsgManage;
public static String TAG="xdysdk";
/*当前播放视频的id*/
private String currentPlayId="";
/*缓存管理*/
private static ACache aCache;
//TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏)
private SurfaceView mSurfaceView_Publish;
private Activity mActivity;
/*是否正在推流,mcu自动断开的时候使用,推流成功后才表示正在使用*/
private boolean isPublisher =false;
// /*Audio 推送中,resume需要使用*/
private boolean isPublisherAudio=false;
/*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/
private boolean isReconnection=false;
/*是否进行录制回放*/
private boolean isRecordPlayBack=false;
/*观察者集合*/
private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>();
/*推流地址*/
private String publish_url="";
/*保存nodeid ,自己的唯一标识*/
private int nodeId=0;
@Override
public void add(ObserverListener observerListener) {
observerListenerList.add(observerListener);
}
@Override
public void notifyObserver(String type, String parameter) {
handleData(type,parameter);
XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter);
}
@Override
public void remove(ObserverListener observerListener) {
if(observerListenerList!=null){
if(observerListenerList.contains(observerListener)) {
observerListenerList.remove(observerListener);
}
}
}
private XdySdk(){}
private static Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.LEAVE_CLASS_CODE){
if(!NetWorkUtils.isNetworkConnected(mContext)) {
if (mXdySdk != null) {
mXdySdk.onPublisherStop();
handler.removeCallbacksAndMessages(null);
}
}
}
}
};
/**
* 初始化
* @param context
*/
public static void init(final Context context){
if(context==null){
throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL);
}
aCache=ACache.get(context);
mContext=context;
mXdyJsCore = XdyJsCore.getInstance(context);
mMsgManage=MsgManage.getErrorMsgInstance();
}
/**
* 接收用户传递进来的参数(两个String 的参数都在这里处理)
* @param type 类型
* @param argument 参数
*/
public void api(final String type, final String argument){
judgeCore();
//再次停止播放器
switch (type){
case "stopPublishAudio":
//停止推送音频
case "stopPublishVideo":
//停止推流video(关闭视频:根据api)
onPublisherStop();
break;
case "stopAudio":
//停止播放audio()
case"stopVideo":
//停止播放video( 停止播放:根据api)
onPlayDestroy();
break;
}
handler.post(new Runnable() {
@Override
public void run() {
mXdyJsCore.native2js(type, argument);
}
});
}
/**
*
* @param type
* @param
* @param surfaceView
* @param activity
* @param
*
*/
public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) {
judgeString(type);
switch (type) {
case Constants.PLAY_AUDIO:
//判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_audio= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_audio)){
//TODO/给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Audio Can not find this mediaId");
return;
}
currentPlayId=mediaId;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class);
if(audioPlayBean!=null) {
String play_url_audio="";
if(isRecordPlayBack){
//如果是回放给出。m3u8的id用户 用户需要自己获取play_url_audio=audioPlayBean.getReplay();
}else{
play_url_audio=audioPlayBean.getRtmpUrl() ;
if(mXdyPlayerCore==null) {
mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_audio, activity);
}else{
mXdyPlayerCore.onStopPlay();
}
mXdyPlayerCore.playAudio(play_url_audio, new EventHande_Play());
}
}else{
XdyLogUtil.e(TAG,"Can not get play Audio response");
}
break;
case Constants.PLAY_VIDEO:
//播放视频
// 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_video= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this mediaId");
return;
}
currentPlayId=mediaId;
VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
String play_url_video="";
if(isRecordPlayBack){
// play_url_video=videoPlayBean.getReplay();
}else{
play_url_video=videoPlayBean.getRtmpUrl();
if(mXdyPlayerCore==null) {
mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_video, activity);
}else{
//重复播放时候
mXdyPlayerCore.onStopPlay();
}
mXdyPlayerCore.playVideo(play_url_video, surfaceView,new EventHande_Play());
}
}else{
//统一提示推流错误
XdyLogUtil.e(TAG,"Can not get play Video response");
}
break;
case Constants.PUBLISH_VIDEO:
/**
* 用户发起这个推流的请求的时候,
* 1,去获取推流地址
* 2,判断地址时候有用,有用的话打开播放器,开启推流的过程
* 3,推流成功告知后台,和用户
*/
getPublishPathVideo();
mSurfaceView_Publish=surfaceView;
mActivity=activity;
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
getPublishPathAudio();
// mSurfaceView=surfaceView;
mActivity=activity;
break;
}
}
/*判断是否被初始化*/
private void judgeCore(){
if(mXdyJsCore==null){
throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT);
}
}
/*判断type是否为空*/
private void judgeString(String type){
if(TextUtils.isEmpty(type)){
XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL);
}
}
/*判断是否是合法的url*/
protected void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
public static XdySdk getXdyInstance(){
if(mXdySdk ==null){
synchronized (XdySdk.class){
mXdySdk =new XdySdk();
}
}
return mXdySdk;
}
/**
*core获取到的数据处理
* @param type
* @param response
*/
private void handleData(String type,String response){
//开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url
/*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和
audio
plublisher Video
publisher Audio
*/
switch (type) {
case Constants.CLASS_JOIN_SUCCESS:
//判断是否是录制回放,调整播流地址
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack");
nodeId=jsonObject.optInt("nodeId");
} catch (JSONException e) {
e.printStackTrace();
}
handleListener(type,response);
break;
case Constants.VIDEO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
// String publishPath=XdyStringUtils.stringToJson(response);
String publishPath=response;
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null) {
//可以推流了
if (getPublishPathReceiveBean.getCode() == 0) {
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路
String video_url = getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url);
//判断
if (mSurfaceView_Publish == null) {
//todo 输出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW);
}
if (mActivity == null) {
//TODo 给出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY);
}
if (mXdyPublisherCore == null) {
mXdyPublisherCore = new XdyPublisherCore(1, 1, mActivity);
}else{
//todo 如果不为空的话是已经播放过,得清理上次的
mXdyPlayerCore.onPause();
}
publish_url=video_url;
isPublisher =true;
isPublisherAudio=false;
mXdyPublisherCore.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish());
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
setPublishSendSuccessVideo(video_url);
}else{
mMsgManage.getPublishVideoPathError();
}
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.AUDIO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
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();
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
aCache.put(Constants.GET_VIDEO_PUBLISH_PATH,audio_url);
//判断
// if (mSurfaceView==null){
// //todo 输出提示
// XdyLogUtil.e(TAG,"surfaceView is null");
// return;
// }
if(mActivity==null){
//TODo 给出提示
XdyLogUtil.e(TAG,"activity is null");
return;
}
if(mXdyPublisherCore==null) {
mXdyPublisherCore = new XdyPublisherCore(1, 0, mActivity);
}else {
//todo 如果不为空的话是已经播放过,得清理上次的
mXdyPlayerCore.onPause();
}
mXdyPublisherCore.publisherAudio(audio_url,new EventHande_Publish());
publish_url=audio_url;
isPublisher =true;
isPublisherAudio=true;
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessAudio(audio_url);
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
//接收后台是否接收到推流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.VIDEO_PUBLISH_RESULT:
//接收发送推流地址给后台返回的信息
String publishReplay=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay));
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class);
if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.VIDEO_PLAY:
//获取推流的地址,需要保存起来
//解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况
String video=response;
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class);
if(videoPlayBean!=null) {
// if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) {
if(nodeId!=videoPlayBean.getFromNodeId()) {
//过滤自己推送的video
aCache.put(videoPlayBean.getMediaId() + "", video);
handleListener(type, videoPlayBean.getMediaId() + "");
}
}else{
XdyLogUtil.e(TAG,"video play json error");
}
break;
case Constants.AUDIO_PLAY:
String audio=response;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class);
if(audioPlayBean!=null){
// if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) {
if(nodeId!=audioPlayBean.getFromNodeId()) {
aCache.put(audioPlayBean.getMediaId() + "", audio);
handleListener(type, audioPlayBean.getMediaId() + "");
}
}
break;
case Constants.ERROR_CODE:
ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class);
if(errorCodeEntity!=null){
if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){
/**
* 方案 一 1,正在直播的时候mcu无故断开,需要重新连接
* 2,class exit 时候主动课堂停止,停止推流
* 利用mcu的生命周期,加入课堂成功后去请求数据
*/
// 方案 二 mcu 断开,页面也断开,用户需要手动重新调用
if(isPublisher) {
if(!NetWorkUtils.isNetworkConnected(mContext)){
//todo判断是否有网络,没有网络的话就让其退出
// TOdo 延迟5秒,
// onPublisherStop();
handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION);
}
isReconnection=true;
}
}
}
handleListener(type,response);
break;
case Constants.CLASS_EXIT:
/**
* 处理正在推流视频,课堂退出的情况,(用户操作退出界面)
* 此时,停止推流,清除surfaceview Activtity 数据,url数据
*/
if(isPublisher){
onPublisherStop();
}
handleListener(type,response);
break;
default:{
handleListener(type,response);
}
}
}
/**
* 处理所有向外发送的接口数据
* @param type
* @param parameter
*/
private void handleListener(String type,String parameter){
XdyLogUtil.e(TAG,"type:"+type+"parameter:"+parameter);
for(ObserverListener o:observerListenerList){
o.observerUpData(type,parameter);
}
}
/**
* 销毁播放音视频
* @param id
* @return
*/
public boolean onPlayStop(String id){
if(currentPlayId.equals(id)) {
if (mXdyPlayerCore != null) {
mXdyPlayerCore.onStopPlay();
// mXdyPlayerCore = null;
}
return true;
}
return false;
}
/**
* 退出时清除信息(重置js监听)
*/
public void removeAll(){
if(mXdyPlayerCore!=null) {
mXdyPlayerCore.onPause();
}
if(mXdyJsCore!=null&&!isRecordPlayBack) {
mXdyJsCore.init(mContext);
}
onPublisherStop();
}
/**
* 结束时调用
*/
public void onPlayDestroy(){
if (mXdyPlayerCore != null) {
mXdyPlayerCore.onStopPlay();
mXdyPlayerCore = null;
}
}
/**
* 推送视频音频停止方法(最后调用的方法)
* @deprecated daniu sdk handle best
*/
public void onPublisherStop(){
if(mXdyPublisherCore!=null){
mXdyPublisherCore.onStopPublisher();
mXdyPublisherCore=null;
}
//如果正在推流,msurfaceView ,mActivity不清空
if(!isPublisher) {
if (mSurfaceView_Publish != null) {
mSurfaceView_Publish = null;
}
if (mActivity != null) {
mActivity = null;
}
}
isPublisher =false;
isReconnection=false;
isPublisherAudio=false;
}
/**
* onPause 方法时走的周期
*/
public void onPublisherPause(){
if(mXdyPublisherCore!=null){
mXdyPublisherCore.onPausePublisher();
}
}
/**
*
* TODO 只有一个boolean
* 开始isPublish 为false
* 开始推流初始化后onresume 就是开始
* @deprecated 大牛 sdk处理的更好
*/
public void onPublisherResume(){
if(!isPublisher){
return;
}
if(mXdyPublisherCore!=null) {
mXdyPublisherCore.onResumePublisher();
if (!TextUtils.isEmpty(publish_url)) {
if(!isPublisherAudio){
mXdyPublisherCore.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish());
}else{
mXdyPublisherCore.publisherAudio(publish_url,new EventHande_Publish());
}
}
}
}
class EventHande_Play implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
class EventHande_Publish implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
/**
* 向后台发送推流数据(Auido)成功信息
* @param url
*/
protected static void setPublishSendSuccessAudio(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp);
}
}
/**
* 向后台发送推流(Video)成功的信息
* @param url
*/
protected static void setPublishSendSuccessVideo(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+"");
XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp);
}
}
}
... ...
package com.mang.xdy;
/**
* Created by abao on 2017/3/30.
*/
public class ss {
}
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装的是使用Gson解析json的方法
*
* @author Administrator
*/
public class JsonUtil {
private static final String TAG = JsonUtil.class.getSimpleName();
/**
* 把一个map变成json字符串
*
* @param map
* @return
*/
public static String parseMapToJson(Map<?, ?> map) {
try {
Gson gson = new Gson();
return gson.toJson(map);
} catch (Exception e) {
}
return null;
}
public static String parseListToJson(List<?> list) {
try {
Gson gson = new Gson();
return gson.toJson(list);
} catch (Exception e) {
}
return null;
}
/**
* 把一个json字符串变成对象
*
* @param json
* @param cls
* @return
*/
public static <T> T parseJsonToBean(String json, Class<T> cls) {
Gson gson = new Gson();
T t = null;
try {
t = gson.fromJson(json, cls);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
return t;
}
/**
* 把json字符串变成map
*
* @param json
* @return
*/
public static HashMap<String, Object> parseJsonToMap(String json) {
Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
HashMap<String, Object> map = null;
try {
map = gson.fromJson(json, type);
} catch (Exception e) {
}
return map;
}
/**
* 把json字符串变成集合
* params: new TypeToken<List<yourbean>>(){}.getType(),
*
* @param json
* @param type new TypeToken<List<yourbean>>(){}.getType()
* @return
*/
public static List<?> parseJsonToList(String json, Type type) {
Gson gson = new Gson();
List<?> list = gson.fromJson(json, type);
return list;
}
/**
* 获取json串中某个字段的值,注意,只能获取同一层级的value
*
* @param json
* @param key
* @return
*/
public static String getFieldValue(String json, String key) {
if (TextUtils.isEmpty(json))
return null;
if (!json.contains(key))
return "";
JSONObject jsonObject = null;
String value = null;
try {
jsonObject = new JSONObject(json);
value = jsonObject.getString(key);
} catch (JSONException e) {
e.printStackTrace();
}
return value;
}
}
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装的是使用Gson解析json的方法
*
* @author abao
*/
public class JsonUtil {
private static final String TAG = JsonUtil.class.getSimpleName();
/**
* 把一个map变成json字符串
*
* @param map
* @return
*/
public static String parseMapToJson(Map<?, ?> map) {
try {
Gson gson = new Gson();
return gson.toJson(map);
} catch (Exception e) {
}
return null;
}
public static String parseListToJson(List<?> list) {
try {
Gson gson = new Gson();
return gson.toJson(list);
} catch (Exception e) {
}
return null;
}
/**
* 把一个json字符串变成对象
*
* @param json
* @param cls
* @return
*/
public static <T> T parseJsonToBean(String json, Class<T> cls) {
Gson gson = new Gson();
T t = null;
try {
t = gson.fromJson(json, cls);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
return t;
}
/**
* 把json字符串变成map
*
* @param json
* @return
*/
public static HashMap<String, Object> parseJsonToMap(String json) {
Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
HashMap<String, Object> map = null;
try {
map = gson.fromJson(json, type);
} catch (Exception e) {
}
return map;
}
/**
* 把json字符串变成集合
* params: new TypeToken<List<yourbean>>(){}.getType(),
*
* @param json
* @param type new TypeToken<List<yourbean>>(){}.getType()
* @return
*/
public static List<?> parseJsonToList(String json, Type type) {
Gson gson = new Gson();
List<?> list = gson.fromJson(json, type);
return list;
}
/**
* 获取json串中某个字段的值,注意,只能获取同一层级的value
*
* @param json
* @param key
* @return
*/
public static String getFieldValue(String json, String key) {
if (TextUtils.isEmpty(json))
return null;
if (!json.contains(key))
return "";
JSONObject jsonObject = null;
String value = null;
try {
jsonObject = new JSONObject(json);
value = jsonObject.getString(key);
} catch (JSONException e) {
e.printStackTrace();
}
return value;
}
}
... ...
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;
/**
* Created by abao on 2017/3/30.
*/
public class XdyStringUtils {
private static String TAG="xdysdk";
public static String stringToJson(String s,boolean isJSjson){
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++){
char c =s.charAt(i);
switch(c){
case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break;
case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break;
case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码
case'/': sb.append("\\/");break;
case'\b':sb.append("\\b");break;//退格
case'\f':sb.append("\\f");break;//走纸换页
case'\n':sb.append("\\n");break;//换行
case'\r':sb.append("\\r");break;//回车
case'\t':sb.append("\\t");break;//横向跳格
default: sb.append(c);
}}
return sb.toString();
}
public static String stringToJson(String s){
// StringBuffer sb = new StringBuffer();
// for(int i=0; i<s.length(); i++){
// char c =s.charAt(i);
// switch(c){
//// case'\"': sb.append(""); break;
// case'\'': sb.append(""); break;
// default: sb.append(c);
// }}
String resString="";
if(!TextUtils.isEmpty(s)&&s.length()>2) {
String temp = s.replace("\\", "");
resString = temp.substring(1, temp.length() - 1);
}
return resString;
}
public static void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
/**
* 时间
* @param currentTime
* @return
*/
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
}
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;
/**
* Created by abao on 2017/3/30.
*/
public class XdyStringUtils {
private static String TAG="xdysdk";
public static String stringToJson(String s,boolean isJSjson){
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++){
char c =s.charAt(i);
switch(c){
case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break;
case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break;
case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码
case'/': sb.append("\\/");break;
case'\b':sb.append("\\b");break;//退格
case'\f':sb.append("\\f");break;//走纸换页
case'\n':sb.append("\\n");break;//换行
case'\r':sb.append("\\r");break;//回车
case'\t':sb.append("\\t");break;//横向跳格
default: sb.append(c);
}}
return sb.toString();
}
public static String stringToJson(String s){
String resString="";
if(!TextUtils.isEmpty(s)&&s.length()>2) {
String temp = s.replace("\\", "");
resString = temp.substring(1, temp.length() - 1);
}
return resString;
}
public static void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
/**
* 时间
* @param currentTime
* @return
*/
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
}
... ...