正在显示
16 个修改的文件
包含
2317 行增加
和
2580 行删除
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <project version="4"> | 2 | <project version="4"> |
| 3 | - <component name="EntryPointsManager"> | ||
| 4 | - <entry_points version="2.0" /> | ||
| 5 | - </component> | ||
| 6 | - <component name="NullableNotNullManager"> | ||
| 7 | - <option name="myDefaultNullable" value="android.support.annotation.Nullable" /> | ||
| 8 | - <option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> | ||
| 9 | - <option name="myNullables"> | ||
| 10 | - <value> | ||
| 11 | - <list size="4"> | ||
| 12 | - <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" /> | ||
| 13 | - <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" /> | ||
| 14 | - <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" /> | ||
| 15 | - <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" /> | ||
| 16 | - </list> | ||
| 17 | - </value> | ||
| 18 | - </option> | ||
| 19 | - <option name="myNotNulls"> | ||
| 20 | - <value> | ||
| 21 | - <list size="4"> | ||
| 22 | - <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" /> | ||
| 23 | - <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" /> | ||
| 24 | - <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" /> | ||
| 25 | - <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" /> | ||
| 26 | - </list> | ||
| 27 | - </value> | ||
| 28 | - </option> | ||
| 29 | - </component> | ||
| 30 | <component name="ProjectLevelVcsManager" settingsEditedManually="false"> | 3 | <component name="ProjectLevelVcsManager" settingsEditedManually="false"> |
| 31 | <OptionsSetting value="true" id="Add" /> | 4 | <OptionsSetting value="true" id="Add" /> |
| 32 | <OptionsSetting value="true" id="Remove" /> | 5 | <OptionsSetting value="true" id="Remove" /> |
| 1 | -apply plugin: 'com.android.application' | ||
| 2 | - | ||
| 3 | -android { | ||
| 4 | - compileSdkVersion 25 | ||
| 5 | - buildToolsVersion '25.0.2' | ||
| 6 | - | ||
| 7 | - defaultConfig { | ||
| 8 | - applicationId "com.mang.xdy.demo" | ||
| 9 | - minSdkVersion 15 | ||
| 10 | - targetSdkVersion 22 | ||
| 11 | - versionCode 1 | ||
| 12 | - versionName "1.0" | ||
| 13 | - | ||
| 14 | - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | ||
| 15 | - | ||
| 16 | - } | ||
| 17 | - buildTypes { | ||
| 18 | - release { | ||
| 19 | - minifyEnabled false | ||
| 20 | - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
| 21 | - } | ||
| 22 | - } | ||
| 23 | - repositories { | ||
| 24 | - flatDir { | ||
| 25 | - dirs 'libs' | ||
| 26 | - } | ||
| 27 | - } | ||
| 28 | -} | ||
| 29 | - | ||
| 30 | -dependencies { | ||
| 31 | - compile fileTree(include: ['*.jar'], dir: 'libs') | ||
| 32 | - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { | ||
| 33 | - exclude group: 'com.android.support', module: 'support-annotations' | ||
| 34 | - }) | ||
| 35 | - compile project(':xdy') | ||
| 36 | - | ||
| 37 | - | ||
| 38 | - compile files('libs/pldroid-player-1.5.1.jar') | ||
| 39 | - compile 'com.android.support:appcompat-v7:25.3.1' | ||
| 40 | - compile 'com.jakewharton:butterknife:8.5.1' | ||
| 41 | - compile 'com.android.support:design:25.3.1' | ||
| 42 | - compile 'com.squareup.picasso:picasso:2.3.2' | ||
| 43 | - compile 'com.github.bumptech.glide:glide:3.7.0' | ||
| 44 | - compile 'com.rockerhieu.emojicon:library:1.3.1' | ||
| 45 | - compile 'org.kymjs.kjframe:kjframe:2.6' | ||
| 46 | - compile 'io.reactivex:rxjava:1.0.9' | ||
| 47 | - compile 'io.reactivex:rxandroid:0.24.0' | ||
| 48 | - compile 'com.squareup.retrofit:retrofit:1.9.0' | ||
| 49 | - compile 'com.nineoldandroids:library:2.4.0' | ||
| 50 | - compile 'me.yokeyword:fragmentation:0.10.3' | ||
| 51 | - compile 'com.qiniu:happy-dns:0.2.+' | ||
| 52 | - compile 'com.android.support:support-v4:25.3.1' | ||
| 53 | - testCompile 'junit:junit:4.12' | ||
| 54 | - annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' | ||
| 55 | - compile 'com.qiniu:happy-dns:0.2.+' | ||
| 56 | - compile 'org.greenrobot:eventbus:3.0.0' | ||
| 57 | -} | 1 | +apply plugin: 'com.android.application' |
| 2 | + | ||
| 3 | +android { | ||
| 4 | + compileSdkVersion 25 | ||
| 5 | + buildToolsVersion '25.0.2' | ||
| 6 | + | ||
| 7 | + defaultConfig { | ||
| 8 | + applicationId "com.mang.xdy.demo" | ||
| 9 | + minSdkVersion 15 | ||
| 10 | + targetSdkVersion 22 | ||
| 11 | + versionCode 1 | ||
| 12 | + versionName "1.0" | ||
| 13 | + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | ||
| 14 | + | ||
| 15 | + } | ||
| 16 | + buildTypes { | ||
| 17 | + release { | ||
| 18 | + minifyEnabled false | ||
| 19 | + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
| 20 | + } | ||
| 21 | + } | ||
| 22 | + repositories { | ||
| 23 | + flatDir { | ||
| 24 | + dirs 'libs' | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +dependencies { | ||
| 30 | + compile fileTree(include: ['*.jar'], dir: 'libs') | ||
| 31 | + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { | ||
| 32 | + exclude group: 'com.android.support', module: 'support-annotations' | ||
| 33 | + }) | ||
| 34 | + compile project(':xdy') | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + compile files('libs/pldroid-player-1.5.1.jar') | ||
| 38 | + compile 'com.android.support:appcompat-v7:25.3.1' | ||
| 39 | + compile 'com.jakewharton:butterknife:8.5.1' | ||
| 40 | + compile 'com.android.support:design:25.3.1' | ||
| 41 | + compile 'com.squareup.picasso:picasso:2.3.2' | ||
| 42 | + compile 'com.github.bumptech.glide:glide:3.7.0' | ||
| 43 | + compile 'com.rockerhieu.emojicon:library:1.3.1' | ||
| 44 | + compile 'org.kymjs.kjframe:kjframe:2.6' | ||
| 45 | + compile 'io.reactivex:rxjava:1.0.9' | ||
| 46 | + compile 'io.reactivex:rxandroid:0.24.0' | ||
| 47 | + compile 'com.squareup.retrofit:retrofit:1.9.0' | ||
| 48 | + compile 'com.nineoldandroids:library:2.4.0' | ||
| 49 | + compile 'me.yokeyword:fragmentation:0.10.3' | ||
| 50 | + compile 'com.qiniu:happy-dns:0.2.+' | ||
| 51 | + compile 'com.android.support:support-v4:25.3.1' | ||
| 52 | + testCompile 'junit:junit:4.12' | ||
| 53 | + annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' | ||
| 54 | + compile 'com.qiniu:happy-dns:0.2.+' | ||
| 55 | + compile 'org.greenrobot:eventbus:3.0.0' | ||
| 56 | +} |
| 1 | -package com.mang.xdy.demo; | ||
| 2 | - | ||
| 3 | -import android.content.Intent; | ||
| 4 | -import android.os.Bundle; | ||
| 5 | -import android.support.v7.app.AppCompatActivity; | ||
| 6 | -import android.text.TextUtils; | ||
| 7 | -import android.view.View; | ||
| 8 | -import android.widget.Button; | ||
| 9 | -import android.widget.EditText; | ||
| 10 | - | ||
| 11 | -import com.google.gson.Gson; | ||
| 12 | - | ||
| 13 | -import com.mang.xdy.demo.activity.VideoPlayActivity; | ||
| 14 | -import com.mang.xdy.demo.bean.JoinClass; | ||
| 15 | -import com.mang.xdy.demo.bean.JoinClassBean; | ||
| 16 | -import com.mang.xdy.demo.utils.ToastUtil; | ||
| 17 | -import com.mang.xdy.utils.XdyLogUtil; | ||
| 18 | - | ||
| 19 | -import java.util.ArrayList; | ||
| 20 | - | ||
| 21 | -import butterknife.BindView; | ||
| 22 | -import butterknife.ButterKnife; | ||
| 23 | -import butterknife.OnClick; | ||
| 24 | - | ||
| 25 | -public class MainActivity extends AppCompatActivity { | ||
| 26 | - | ||
| 27 | - @BindView(R.id.edt_home_classId) | ||
| 28 | - EditText edtHomeClassId; | ||
| 29 | - @BindView(R.id.edt_home_role) | ||
| 30 | - EditText edtHomeRole; | ||
| 31 | - @BindView(R.id.edt_home_serviceIp) | ||
| 32 | - EditText edtHomeServiceIp; | ||
| 33 | - @BindView(R.id.edt_home_userId) | ||
| 34 | - EditText edtHomeUserId; | ||
| 35 | - @BindView(R.id.btn_home_enter_class) | ||
| 36 | - Button btnHomeEnterClass; | ||
| 37 | - @BindView(R.id.btn_home_enter_publisher) | ||
| 38 | - Button btn_home_enter_publisher; | ||
| 39 | - @BindView(R.id.btn_home_enter_publisherAudio) | ||
| 40 | - Button btn_home_enter_publisherAudio; | ||
| 41 | - /*一进来就要初始化,让后再调 加入课堂*/ | ||
| 42 | - @Override | ||
| 43 | - protected void onCreate(Bundle savedInstanceState) { | ||
| 44 | - super.onCreate(savedInstanceState); | ||
| 45 | - setContentView(R.layout.activity_main); | ||
| 46 | - ButterKnife.bind(this); | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - @OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher,R.id.btn_home_enter_publisherAudio}) | ||
| 50 | - public void onViewClicked(View view) { | ||
| 51 | - if(TextUtils.isEmpty(joinClass())){ | ||
| 52 | - return; | ||
| 53 | - } | ||
| 54 | - ArrayList<String> arrayList=new ArrayList<>(); | ||
| 55 | - switch (view.getId()){ | ||
| 56 | - | ||
| 57 | - case R.id.btn_home_enter_class: | ||
| 58 | - Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class); | ||
| 59 | - arrayList.clear(); | ||
| 60 | - arrayList.add(joinClass()); | ||
| 61 | - arrayList.add("normal"); | ||
| 62 | - intent.putStringArrayListExtra("init",arrayList); | ||
| 63 | - startActivity(intent); | ||
| 64 | - break; | ||
| 65 | - case R.id.btn_home_enter_publisher: | ||
| 66 | - Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class); | ||
| 67 | - arrayList.clear(); | ||
| 68 | - arrayList.add(joinClass()); | ||
| 69 | - arrayList.add(""); | ||
| 70 | - intents.putStringArrayListExtra("init",arrayList); | ||
| 71 | - startActivity(intents); | ||
| 72 | - break; | ||
| 73 | - case R.id.btn_home_enter_publisherAudio: | ||
| 74 | -// Intent intent_audio=new Intent(MainActivity.this, AudioPublisherActivity.class); | ||
| 75 | -// intent_audio.putExtra("init",joinClass()); | ||
| 76 | -// startActivity(intent_audio); | ||
| 77 | - break; | ||
| 78 | - } | ||
| 79 | - } | ||
| 80 | - private String classId=""; | ||
| 81 | - private String userRole=""; | ||
| 82 | - private String serviceIp=""; | ||
| 83 | - private String userId=""; | ||
| 84 | - public boolean getLoginInfo(){ | ||
| 85 | - classId=edtHomeClassId.getText().toString(); | ||
| 86 | - userRole=edtHomeRole.getText().toString(); | ||
| 87 | - serviceIp=edtHomeServiceIp.getText().toString(); | ||
| 88 | - userId=edtHomeUserId.getText().toString(); | ||
| 89 | - if(TextUtils.isEmpty(classId)){ | ||
| 90 | - ToastUtil.showToast("课堂Id不能为空",this); | ||
| 91 | - return false; | ||
| 92 | - } | ||
| 93 | - if(TextUtils.isEmpty(serviceIp)){ | ||
| 94 | - ToastUtil.showToast("服务器地址不能为空",this); | ||
| 95 | - return false; | ||
| 96 | - } | ||
| 97 | - if(TextUtils.isEmpty(userRole)){ | ||
| 98 | - ToastUtil.showToast("角色不能为空",this); | ||
| 99 | - return false; | ||
| 100 | - } | ||
| 101 | - if(TextUtils.isEmpty(userId)){ | ||
| 102 | - ToastUtil.showToast("用户id不能为空",this); | ||
| 103 | - return false; | ||
| 104 | - } | ||
| 105 | - return true; | ||
| 106 | - } | ||
| 107 | - public String joinClass(){ | ||
| 108 | - if(getLoginInfo()) { | ||
| 109 | - JoinClassBean joinClassBean = new JoinClassBean(); | ||
| 110 | - joinClassBean.setClassId(Integer.parseInt(classId)); | ||
| 111 | - joinClassBean.setUserRole(userRole); | ||
| 112 | - joinClassBean.setPortal(serviceIp); | ||
| 113 | - joinClassBean.setUserId(Integer.parseInt(userId)); | ||
| 114 | - joinClassBean.setUserName(""); | ||
| 115 | - String joinclass = new Gson().toJson(joinClassBean); | ||
| 116 | -// XdyLogUtil.e("init 初始化", joinclass); | ||
| 117 | - return joinclass; | ||
| 118 | - }else{ | ||
| 119 | - return ""; | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - } | ||
| 123 | -} | 1 | +package com.mang.xdy.demo; |
| 2 | + | ||
| 3 | +import android.content.Intent; | ||
| 4 | +import android.os.Bundle; | ||
| 5 | +import android.support.v7.app.AppCompatActivity; | ||
| 6 | +import android.text.TextUtils; | ||
| 7 | +import android.view.View; | ||
| 8 | +import android.widget.Button; | ||
| 9 | +import android.widget.EditText; | ||
| 10 | + | ||
| 11 | +import com.google.gson.Gson; | ||
| 12 | + | ||
| 13 | +import com.mang.xdy.demo.activity.VideoPlayActivity; | ||
| 14 | +import com.mang.xdy.demo.bean.JoinClassBean; | ||
| 15 | +import com.mang.xdy.demo.utils.ToastUtil; | ||
| 16 | + | ||
| 17 | +import java.util.ArrayList; | ||
| 18 | + | ||
| 19 | +import butterknife.BindView; | ||
| 20 | +import butterknife.ButterKnife; | ||
| 21 | +import butterknife.OnClick; | ||
| 22 | + | ||
| 23 | +public class MainActivity extends AppCompatActivity { | ||
| 24 | + | ||
| 25 | + @BindView(R.id.edt_home_classId) | ||
| 26 | + EditText edtHomeClassId; | ||
| 27 | + @BindView(R.id.edt_home_role) | ||
| 28 | + EditText edtHomeRole; | ||
| 29 | + @BindView(R.id.edt_home_serviceIp) | ||
| 30 | + EditText edtHomeServiceIp; | ||
| 31 | + @BindView(R.id.edt_home_userId) | ||
| 32 | + EditText edtHomeUserId; | ||
| 33 | + @BindView(R.id.btn_home_enter_class) | ||
| 34 | + Button btnHomeEnterClass; | ||
| 35 | + @BindView(R.id.btn_home_enter_publisher) | ||
| 36 | + Button btn_home_enter_publisher; | ||
| 37 | + /*一进来就要初始化,让后再调 加入课堂*/ | ||
| 38 | + @Override | ||
| 39 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 40 | + super.onCreate(savedInstanceState); | ||
| 41 | + setContentView(R.layout.activity_main); | ||
| 42 | + ButterKnife.bind(this); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher}) | ||
| 46 | + public void onViewClicked(View view) { | ||
| 47 | + if(TextUtils.isEmpty(joinClass())){ | ||
| 48 | + return; | ||
| 49 | + } | ||
| 50 | + ArrayList<String> arrayList=new ArrayList<>(); | ||
| 51 | + switch (view.getId()){ | ||
| 52 | + | ||
| 53 | + case R.id.btn_home_enter_class: | ||
| 54 | + Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class); | ||
| 55 | + arrayList.clear(); | ||
| 56 | + arrayList.add(joinClass()); | ||
| 57 | + arrayList.add("normal"); | ||
| 58 | + intent.putStringArrayListExtra("init",arrayList); | ||
| 59 | + startActivity(intent); | ||
| 60 | + break; | ||
| 61 | + case R.id.btn_home_enter_publisher: | ||
| 62 | + Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class); | ||
| 63 | + arrayList.clear(); | ||
| 64 | + arrayList.add(joinClass()); | ||
| 65 | + arrayList.add(""); | ||
| 66 | + intents.putStringArrayListExtra("init",arrayList); | ||
| 67 | + startActivity(intents); | ||
| 68 | + break; | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + private String classId=""; | ||
| 72 | + private String userRole=""; | ||
| 73 | + private String serviceIp=""; | ||
| 74 | + private String userId=""; | ||
| 75 | + public boolean getLoginInfo(){ | ||
| 76 | + classId=edtHomeClassId.getText().toString(); | ||
| 77 | + userRole=edtHomeRole.getText().toString(); | ||
| 78 | + serviceIp=edtHomeServiceIp.getText().toString(); | ||
| 79 | + userId=edtHomeUserId.getText().toString(); | ||
| 80 | + if(TextUtils.isEmpty(classId)){ | ||
| 81 | + ToastUtil.showToast("课堂Id不能为空",this); | ||
| 82 | + return false; | ||
| 83 | + } | ||
| 84 | + if(TextUtils.isEmpty(serviceIp)){ | ||
| 85 | + ToastUtil.showToast("服务器地址不能为空",this); | ||
| 86 | + return false; | ||
| 87 | + } | ||
| 88 | + if(TextUtils.isEmpty(userRole)){ | ||
| 89 | + ToastUtil.showToast("角色不能为空",this); | ||
| 90 | + return false; | ||
| 91 | + } | ||
| 92 | + if(TextUtils.isEmpty(userId)){ | ||
| 93 | + ToastUtil.showToast("用户id不能为空",this); | ||
| 94 | + return false; | ||
| 95 | + } | ||
| 96 | + return true; | ||
| 97 | + } | ||
| 98 | + public String joinClass(){ | ||
| 99 | + if(getLoginInfo()) { | ||
| 100 | + JoinClassBean joinClassBean = new JoinClassBean(); | ||
| 101 | + joinClassBean.setClassId(Integer.parseInt(classId)); | ||
| 102 | + joinClassBean.setUserRole(userRole); | ||
| 103 | + joinClassBean.setPortal(serviceIp); | ||
| 104 | + joinClassBean.setUserId(Integer.parseInt(userId)); | ||
| 105 | + joinClassBean.setUserName(""); | ||
| 106 | + String joinclass = new Gson().toJson(joinClassBean); | ||
| 107 | +// XdyLogUtil.e("init 初始化", joinclass); | ||
| 108 | + return joinclass; | ||
| 109 | + }else{ | ||
| 110 | + return ""; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + } | ||
| 114 | +} |
| 1 | -package com.mang.xdy.demo.activity; | ||
| 2 | -; | ||
| 3 | -import android.annotation.SuppressLint; | ||
| 4 | -import android.app.ProgressDialog; | ||
| 5 | -import android.app.Service; | ||
| 6 | -import android.content.Context; | ||
| 7 | -import android.content.DialogInterface; | ||
| 8 | -import android.graphics.PixelFormat; | ||
| 9 | -import android.hardware.display.VirtualDisplay; | ||
| 10 | -import android.media.projection.MediaProjection; | ||
| 11 | -import android.media.projection.MediaProjectionManager; | ||
| 12 | -import android.os.Bundle; | ||
| 13 | -import android.os.Handler; | ||
| 14 | -import android.os.Message; | ||
| 15 | -import android.support.design.widget.TabLayout; | ||
| 16 | -import android.support.v7.app.AlertDialog; | ||
| 17 | -import android.support.v7.app.AppCompatActivity; | ||
| 18 | -import android.text.TextUtils; | ||
| 19 | -import android.util.DisplayMetrics; | ||
| 20 | -import android.util.Log; | ||
| 21 | -import android.view.Gravity; | ||
| 22 | -import android.view.SurfaceHolder; | ||
| 23 | -import android.view.SurfaceView; | ||
| 24 | -import android.view.View; | ||
| 25 | -import android.view.ViewGroup; | ||
| 26 | -import android.view.WindowManager; | ||
| 27 | -import android.widget.Button; | ||
| 28 | -import android.widget.FrameLayout; | ||
| 29 | -import android.widget.ImageButton; | ||
| 30 | -import android.widget.ImageView; | ||
| 31 | -import android.widget.RelativeLayout; | ||
| 32 | -import android.widget.SeekBar; | ||
| 33 | -import android.widget.TextView; | ||
| 34 | - | ||
| 35 | -import com.google.gson.Gson; | ||
| 36 | -import com.mang.xdy.bean.VideoPlayBean; | ||
| 37 | -import com.mang.xdy.cache.ACache; | ||
| 38 | -import com.mang.xdy.common.Constants; | ||
| 39 | -import com.mang.xdy.core.SPUtil; | ||
| 40 | -import com.mang.xdy.core.XdySdk; | ||
| 41 | -import com.mang.xdy.demo.R; | ||
| 42 | -import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter; | ||
| 43 | -import com.mang.xdy.demo.bean.ErrorEntity; | ||
| 44 | -import com.mang.xdy.demo.bean.InitClassSuccessEntity; | ||
| 45 | -import com.mang.xdy.demo.bean.JoinClass; | ||
| 46 | -import com.mang.xdy.demo.bean.ResponseEntity; | ||
| 47 | -import com.mang.xdy.demo.bean.TimeEntity; | ||
| 48 | -import com.mang.xdy.demo.bean.VideoOrAudioStopEntity; | ||
| 49 | -import com.mang.xdy.demo.utils.JsonUtil; | ||
| 50 | -import com.mang.xdy.demo.utils.ToastUtil; | ||
| 51 | -import com.mang.xdy.demo.widget.dialog.LoginDialog; | ||
| 52 | -import com.mang.xdy.demo.widget.view.NoScrollViewPager; | ||
| 53 | -import com.mang.xdy.listener.ObserverListener; | ||
| 54 | -import com.mang.xdy.utils.UIUtils; | ||
| 55 | -import com.mang.xdy.utils.XdyLogUtil; | ||
| 56 | -import com.mang.xdy.utils.XdyStringUtils; | ||
| 57 | -import com.pili.pldroid.player.AVOptions; | ||
| 58 | -import com.pili.pldroid.player.PLMediaPlayer; | ||
| 59 | -import com.pili.pldroid.player.widget.PLVideoTextureView; | ||
| 60 | -import com.pili.pldroid.player.widget.PLVideoView; | ||
| 61 | -import com.videoengine.NTRenderer; | ||
| 62 | - | ||
| 63 | - | ||
| 64 | -import org.greenrobot.eventbus.EventBus; | ||
| 65 | -import org.json.JSONException; | ||
| 66 | -import org.json.JSONObject; | ||
| 67 | - | ||
| 68 | -import java.util.ArrayList; | ||
| 69 | -import java.util.Locale; | ||
| 70 | - | ||
| 71 | -import butterknife.BindView; | ||
| 72 | -import butterknife.ButterKnife; | ||
| 73 | - | ||
| 74 | -import static com.pili.pldroid.player.AVOptions.KEY_DELAY_OPTIMIZATION; | ||
| 75 | - | ||
| 76 | -public class VideoPlayActivity extends AppCompatActivity implements ObserverListener, PLMediaPlayer.OnErrorListener, PLMediaPlayer.OnInfoListener,NoScrollViewPager.OnRplayTouchListener { | ||
| 77 | - private final static String TAG = "VideoPlayActivity"; | ||
| 78 | - @BindView(R.id.img_playVideo_novideo) | ||
| 79 | - ImageView img_playVideo_novideo; | ||
| 80 | - @BindView(R.id.btn_videoPlay_exit) | ||
| 81 | - Button btn_videoPlay_exit; | ||
| 82 | - private String username = ""; | ||
| 83 | - private String userpwd = ""; | ||
| 84 | - private SimpleFragmentPagerAdapter pagerAdapter; | ||
| 85 | - @BindView(R.id.viewpager) | ||
| 86 | - NoScrollViewPager viewPager; | ||
| 87 | - private TabLayout tabLayout; | ||
| 88 | - @BindView(R.id.surfaceview_playVideo) | ||
| 89 | - SurfaceView surfaceviewPlayVideo; | ||
| 90 | - | ||
| 91 | - @BindView(R.id.fra_videoPlay_publish) | ||
| 92 | - FrameLayout frameLayout_publish; | ||
| 93 | - | ||
| 94 | - @BindView(R.id.btn_videoPlay_stopPublish) | ||
| 95 | - Button btn_videoPlay_stopPublish; | ||
| 96 | - /*推流*/ | ||
| 97 | -// @BindView(R.id.surfaceview_playVideo_text) | ||
| 98 | - SurfaceView mSurfaceView ; | ||
| 99 | - private String initClass = ""; | ||
| 100 | - private XdySdk xdySdk; | ||
| 101 | - private LoginDialog mLoginDialog; | ||
| 102 | - private ProgressDialog mProgressDialog; | ||
| 103 | - @BindView(R.id.img_playVideo_replay) | ||
| 104 | - PLVideoTextureView mVideoView; | ||
| 105 | - private String playVideoOrAudioId=""; | ||
| 106 | - //视频模式还是音频模式 | ||
| 107 | - private boolean isVideoMode=true; | ||
| 108 | - /*mcu断开或者网络原因为false*/ | ||
| 109 | - private boolean isDefaultExit=true; | ||
| 110 | - private AlertDialog mErrorDialog; | ||
| 111 | - | ||
| 112 | - private ACache aCache; | ||
| 113 | - //TODO 默认回放 | ||
| 114 | - private boolean replay = false; | ||
| 115 | - private Handler mmHandler = new Handler() { | ||
| 116 | - @Override | ||
| 117 | - public void handleMessage(Message msg) { | ||
| 118 | - super.handleMessage(msg); | ||
| 119 | - ResponseEntity responseEntity = (ResponseEntity) msg.obj; | ||
| 120 | - switch (responseEntity.getType()) { | ||
| 121 | - | ||
| 122 | - case Constants.CLASS_EXIT: | ||
| 123 | - ToastUtil.showToast("退出课堂",VideoPlayActivity.this); | ||
| 124 | - progressDialogDismiss(); | ||
| 125 | - exit(); | ||
| 126 | - break; | ||
| 127 | - case Constants.ERROR_CODE: | ||
| 128 | - handError(responseEntity.getType(), responseEntity.getParam()); | ||
| 129 | - break; | ||
| 130 | - case Constants.CLASS_INIT_SUCCESS: | ||
| 131 | - String login = responseEntity.getParam(); | ||
| 132 | - parseJoinClass(login, true); | ||
| 133 | - ToastUtil.showToastshort("初始化课堂成功", VideoPlayActivity.this); | ||
| 134 | - break; | ||
| 135 | - case Constants.CLASS_JOIN_SUCCESS: | ||
| 136 | - //加入课堂成功 | ||
| 137 | - progressDialogDismiss(); | ||
| 138 | - UIUtils.closeDialog(mLoginDialog); | ||
| 139 | - ToastUtil.showToastshort("加入课堂成功", VideoPlayActivity.this); | ||
| 140 | - String userJson = responseEntity.getParam(); | ||
| 141 | - SPUtil.putString(VideoPlayActivity.this, Constants.CLASS_JOIN_SUCCESS, userJson); | ||
| 142 | -// JSONObject jsonObject = null; | ||
| 143 | -// try { | ||
| 144 | -// jsonObject = new JSONObject(userJson); | ||
| 145 | -// replay = jsonObject.optBoolean("isRecordPlayBack"); | ||
| 146 | -// } catch (JSONException e) { | ||
| 147 | -// e.printStackTrace(); | ||
| 148 | -// } | ||
| 149 | - if(replay) { | ||
| 150 | - initRecordSeek(userJson); | ||
| 151 | - } | ||
| 152 | - break; | ||
| 153 | - case Constants.VIDEO_PLAY: | ||
| 154 | - //播放视频 | ||
| 155 | - playVideoOrAudioId=responseEntity.getParam(); | ||
| 156 | - isVideoMode=true; | ||
| 157 | - playVideo(responseEntity.getParam()); | ||
| 158 | - break; | ||
| 159 | - case Constants.AUDIO_PLAY: | ||
| 160 | - //播放音频 | ||
| 161 | - isVideoMode=false; | ||
| 162 | - playVideoOrAudioId=responseEntity.getParam(); | ||
| 163 | - playAudio(responseEntity.getParam()); | ||
| 164 | - break; | ||
| 165 | - case Constants.VIDEO_STOP: | ||
| 166 | - //停止播放 | ||
| 167 | - case Constants.AUDIO_STOP: | ||
| 168 | - //停止播放 | ||
| 169 | - stopPlay(responseEntity.getParam()); | ||
| 170 | - break; | ||
| 171 | - case Constants.PLAY_SUCCESS: | ||
| 172 | - //自定义消息 播放视频音频都通过这个来判断 | ||
| 173 | - img_playVideo_novideo.setVisibility(View.GONE); | ||
| 174 | - break; | ||
| 175 | - case Constants.CLASS_UPDATE_TIMER: | ||
| 176 | - if(replay) | ||
| 177 | - handleTime(responseEntity.getParam()); | ||
| 178 | - break; | ||
| 179 | - case Constants.RECORD_PLAYBACK_UPDATE: | ||
| 180 | - handleRecord(responseEntity.getParam()); | ||
| 181 | - break; | ||
| 182 | - | ||
| 183 | - | ||
| 184 | - } | ||
| 185 | - } | ||
| 186 | - }; | ||
| 187 | - | ||
| 188 | - @Override | ||
| 189 | - protected void onCreate(final Bundle savedInstanceState) { | ||
| 190 | - super.onCreate(savedInstanceState); | ||
| 191 | - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //屏幕常亮 | ||
| 192 | - setContentView(R.layout.activity_video_play); | ||
| 193 | - ButterKnife.bind(this); | ||
| 194 | - aCache=ACache.get(this); | ||
| 195 | -// XdySdk.init(this); | ||
| 196 | - xdySdk = XdySdk.getXdyInstance(); | ||
| 197 | - xdySdk.add(this); | ||
| 198 | - init(); | ||
| 199 | - | ||
| 200 | - progressDialogShow(); | ||
| 201 | - setTablayout(); | ||
| 202 | - } | ||
| 203 | - | ||
| 204 | - public void init() { | ||
| 205 | - ArrayList<String> arrayList=getIntent().getStringArrayListExtra("init"); | ||
| 206 | - if(arrayList!=null&&arrayList.size()>1){ | ||
| 207 | - initClass= arrayList.get(0); | ||
| 208 | - if(TextUtils.isEmpty(arrayList.get(1))){ | ||
| 209 | - replay=true; | ||
| 210 | - }else { | ||
| 211 | - replay=false; | ||
| 212 | - } | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - if(!replay){ | ||
| 216 | - mVideoView.setVisibility(View.GONE); | ||
| 217 | - mMediaContainer.setVisibility(View.GONE); | ||
| 218 | -// btn_videoPlay_exit.setVisibility(View.VISIBLE); | ||
| 219 | - }else{ | ||
| 220 | - surfaceviewPlayVideo.setVisibility(View.GONE); | ||
| 221 | - initReplay(); | ||
| 222 | - | ||
| 223 | - } | ||
| 224 | -// initClass = getIntent().getStringExtra("init"); | ||
| 225 | - if(!replay){ | ||
| 226 | - xdySdk.api("init", initClass); | ||
| 227 | - }else{ | ||
| 228 | - xdySdk.api("initRecordPlayback", initClass); | ||
| 229 | -// xdySdk.api("startRecordPlayback", ""); | ||
| 230 | - } | ||
| 231 | - currentTime=0; | ||
| 232 | - btn_videoPlay_stopPublish.setOnClickListener(new View.OnClickListener() { | ||
| 233 | - @Override | ||
| 234 | - public void onClick(View v) { | ||
| 235 | - xdySdk.api("stopPublishVideo", ""); | ||
| 236 | - } | ||
| 237 | - }); | ||
| 238 | - btn_videoPlay_exit.setOnClickListener(new View.OnClickListener() { | ||
| 239 | - @Override | ||
| 240 | - public void onClick(View v) { | ||
| 241 | - if (mSurfaceView == null) { | ||
| 242 | - mSurfaceView = NTRenderer.CreateRenderer(VideoPlayActivity.this, false); | ||
| 243 | - } | ||
| 244 | - btn_videoPlay_stopPublish.setVisibility(View.VISIBLE); | ||
| 245 | - btn_videoPlay_exit.setVisibility(View.GONE); | ||
| 246 | - btn_videoPlay_exit.setEnabled(false); | ||
| 247 | -// mSurfaceView=new SurfaceView(VideoPlayActivity.this); | ||
| 248 | - SurfaceHolder sh = mSurfaceView.getHolder();; | ||
| 249 | - sh.setFormat(PixelFormat.TRANSPARENT); | ||
| 250 | - mSurfaceView.setZOrderOnTop(true); | ||
| 251 | - frameLayout_publish.addView(mSurfaceView); | ||
| 252 | - xdySdk.api("publishVideo", "", mSurfaceView, VideoPlayActivity.this); | ||
| 253 | - isVideoMode=true; | ||
| 254 | - | ||
| 255 | - | ||
| 256 | -// mmHandler.post(new Runnable() { | ||
| 257 | -// @Override | ||
| 258 | -// public void run() { | ||
| 259 | -// initSmall(); | ||
| 260 | -// } | ||
| 261 | -// }); | ||
| 262 | - | ||
| 263 | -// xdySdk.api("leaveClass", ""); | ||
| 264 | - | ||
| 265 | -// | ||
| 266 | -// xdySdk.remove(VideoPlayActivity.this); | ||
| 267 | -// xdySdk.removeAll(); | ||
| 268 | -// UIUtils.closeDialog(mLoginDialog); | ||
| 269 | -// VideoPlayActivity.super.onBackPressed(); | ||
| 270 | -// exit(); | ||
| 271 | -// String id="initRecordPlayback"; | ||
| 272 | -// String param="{\n" + | ||
| 273 | -// " \"classId\": 391813551,\n" + | ||
| 274 | -// " \"portal\": \"112.126.80.182:90\",\n" + | ||
| 275 | -// " \"userRole\": \"normal\",\n" + | ||
| 276 | -// " \"userName\": \"\",\n" + | ||
| 277 | -// " \"userId\": 0\n" + | ||
| 278 | -// "}"; | ||
| 279 | -// String ss=XdyStringUtils.stringToJson(param,true); | ||
| 280 | -// xdySdk.api(id,ss); | ||
| 281 | -// mHandler.postDelayed(new Runnable() { | ||
| 282 | -// @Override | ||
| 283 | -// public void run() { | ||
| 284 | -// xdySdk.api("startRecordPlayback", ""); | ||
| 285 | -// } | ||
| 286 | -// }, 200); | ||
| 287 | - | ||
| 288 | - } | ||
| 289 | - }); | ||
| 290 | - } | ||
| 291 | - | ||
| 292 | - public void setTablayout() { | ||
| 293 | - pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this,replay); | ||
| 294 | - viewPager.setAdapter(pagerAdapter); | ||
| 295 | - viewPager.setOnRplayTouchListener(this); | ||
| 296 | - tabLayout = (TabLayout) findViewById(R.id.sliding_tabs); | ||
| 297 | -// tabLayout.setupWithViewPager(viewPager); | ||
| 298 | - tabLayout.setupWithViewPager(viewPager,false); | ||
| 299 | - tabLayout.setTabMode(TabLayout.MODE_FIXED); | ||
| 300 | - } | ||
| 301 | - | ||
| 302 | - //判断解析是否有密码 | ||
| 303 | - public void parseJoinClass(String rsponse, boolean isShowPwd) { | ||
| 304 | - InitClassSuccessEntity initClassSuccessEntity = JsonUtil.parseJsonToBean(rsponse, InitClassSuccessEntity.class); | ||
| 305 | - if (initClassSuccessEntity != null) { | ||
| 306 | - if (initClassSuccessEntity.isPasswordRequired()) { | ||
| 307 | - isShowPwd = true; | ||
| 308 | - } else { | ||
| 309 | - isShowPwd = false; | ||
| 310 | - userpwd = "123321"; | ||
| 311 | - } | ||
| 312 | - } | ||
| 313 | - if (mLoginDialog == null) { | ||
| 314 | - mLoginDialog = new LoginDialog(this, isShowPwd, null); | ||
| 315 | - mLoginDialog.show(); | ||
| 316 | - progressDialogDismiss(); | ||
| 317 | - mLoginDialog.setCanceledOnTouchOutside(false); | ||
| 318 | - final boolean finalIsShowPwd = isShowPwd; | ||
| 319 | - mLoginDialog.setBtnClick(new View.OnClickListener() { | ||
| 320 | - @Override | ||
| 321 | - public void onClick(View view) { | ||
| 322 | - String[] nameAndPwd = mLoginDialog.getNameAndPwd(); | ||
| 323 | - joinClass(nameAndPwd[0], nameAndPwd[1], finalIsShowPwd); | ||
| 324 | - progressDialogShow(); | ||
| 325 | - } | ||
| 326 | - }); | ||
| 327 | - } else if (mLoginDialog != null) { | ||
| 328 | - UIUtils.closeDialog(mLoginDialog); | ||
| 329 | - } | ||
| 330 | - } | ||
| 331 | - | ||
| 332 | - //加入课堂 | ||
| 333 | - public void joinClass(String rsponse, boolean isShowPwd) { | ||
| 334 | - JoinClass joinClass = new JoinClass(); | ||
| 335 | - joinClass.setHasCamera(false); | ||
| 336 | - joinClass.setHasMicrophone(false); | ||
| 337 | - joinClass.setUserName(username); | ||
| 338 | - if (!isShowPwd) { | ||
| 339 | - joinClass.setPassword("123321"); | ||
| 340 | - } else { | ||
| 341 | - joinClass.setPassword(userpwd); | ||
| 342 | - } | ||
| 343 | - String temp = new Gson().toJson(joinClass); | ||
| 344 | - String jsonParmp = XdyStringUtils.stringToJson(temp, true); | ||
| 345 | - XdyLogUtil.e("加入课堂", jsonParmp); | ||
| 346 | - xdySdk.api("joinClass", jsonParmp); | ||
| 347 | - } | ||
| 348 | - | ||
| 349 | - //加入课堂 | ||
| 350 | - public void joinClass(String username, String userpwd, boolean isShowPwd) { | ||
| 351 | - JoinClass joinClass = new JoinClass(); | ||
| 352 | - joinClass.setHasCamera(false); | ||
| 353 | - joinClass.setHasMicrophone(false); | ||
| 354 | - joinClass.setUserName(username); | ||
| 355 | - if (!isShowPwd) { | ||
| 356 | - joinClass.setPassword("123321"); | ||
| 357 | - } else { | ||
| 358 | - joinClass.setPassword(userpwd); | ||
| 359 | - } | ||
| 360 | - String temp = new Gson().toJson(joinClass); | ||
| 361 | - String jsonParmp = XdyStringUtils.stringToJson(temp, true); | ||
| 362 | - XdyLogUtil.e("加入课堂", jsonParmp); | ||
| 363 | - xdySdk.api("joinClass", jsonParmp); | ||
| 364 | - } | ||
| 365 | - | ||
| 366 | - /** | ||
| 367 | - * 播放视频 | ||
| 368 | - * | ||
| 369 | - * @param response | ||
| 370 | - */ | ||
| 371 | - public void playVideo(String response) { | ||
| 372 | - progressDialogDismiss(); | ||
| 373 | - | ||
| 374 | - if(replay){ | ||
| 375 | - playRecord(response); | ||
| 376 | - | ||
| 377 | - }else { | ||
| 378 | - xdySdk.api("playVideo", response + "", surfaceviewPlayVideo, VideoPlayActivity.this); | ||
| 379 | -// img_playVideo_novideo.setVisibility(View.GONE); | ||
| 380 | - img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 381 | - ToastUtil.showToastshort("视频播放初始化", VideoPlayActivity.this); | ||
| 382 | - } | ||
| 383 | - } | ||
| 384 | - /** | ||
| 385 | - * 播放音频 | ||
| 386 | - * | ||
| 387 | - * @param response | ||
| 388 | - */ | ||
| 389 | - public void playAudio(String response) { | ||
| 390 | - if(replay){ | ||
| 391 | - playRecord(response); | ||
| 392 | - img_playVideo_novideo.setImageResource(R.mipmap.audio_mode); | ||
| 393 | - img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 394 | - }else { | ||
| 395 | - xdySdk.api("playAudio", response, null, VideoPlayActivity.this); | ||
| 396 | - img_playVideo_novideo.setImageResource(R.mipmap.audio_mode); | ||
| 397 | - img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 398 | - ToastUtil.showToastshort("音频播放初始化", VideoPlayActivity.this); | ||
| 399 | - } | ||
| 400 | - } | ||
| 401 | - | ||
| 402 | - @Override | ||
| 403 | - public void onBackPressed() { | ||
| 404 | - final AlertDialog alertDialog = new AlertDialog.Builder(this) | ||
| 405 | - .setTitle("退出") | ||
| 406 | - .setMessage("是否离开课堂") | ||
| 407 | - .setNegativeButton("在看看", new DialogInterface.OnClickListener() { | ||
| 408 | - @Override | ||
| 409 | - public void onClick(DialogInterface dialogInterface, int i) { | ||
| 410 | - dialogInterface.dismiss(); | ||
| 411 | - } | ||
| 412 | - }) | ||
| 413 | - .setPositiveButton("确认", new DialogInterface.OnClickListener() { | ||
| 414 | - @Override | ||
| 415 | - public void onClick(DialogInterface dialogInterface, int i) { | ||
| 416 | - | ||
| 417 | - | ||
| 418 | - //如果收到class_exit 就执行,退出界面 | ||
| 419 | - UIUtils.closeDialog(mLoginDialog); | ||
| 420 | - exit(); | ||
| 421 | -// progressDialogShow(); | ||
| 422 | - } | ||
| 423 | - }) | ||
| 424 | - .create(); | ||
| 425 | - alertDialog.show(); | ||
| 426 | - | ||
| 427 | - | ||
| 428 | - } | ||
| 429 | - | ||
| 430 | - /** | ||
| 431 | - * 错误处理 | ||
| 432 | - * | ||
| 433 | - * @param errorId | ||
| 434 | - * @param errorMsg | ||
| 435 | - */ | ||
| 436 | - public void handError(String errorId, String errorMsg) { | ||
| 437 | - ErrorEntity errorEntity = JsonUtil.parseJsonToBean(errorMsg, ErrorEntity.class); | ||
| 438 | - if (errorEntity == null) { | ||
| 439 | - return; | ||
| 440 | - } | ||
| 441 | - switch (errorEntity.getCode() + "") { | ||
| 442 | - case "100": | ||
| 443 | - case "101": | ||
| 444 | - case "102": | ||
| 445 | - case "103": | ||
| 446 | - case "104": | ||
| 447 | - case "105": | ||
| 448 | - case "106": | ||
| 449 | - case "107": | ||
| 450 | - case "200": | ||
| 451 | - case "201": | ||
| 452 | - case "202": | ||
| 453 | - case "203": | ||
| 454 | - case "204": | ||
| 455 | - case "205": | ||
| 456 | - case "206": | ||
| 457 | - case "207": | ||
| 458 | - case "208": | ||
| 459 | - ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 460 | - exit(); | ||
| 461 | - break; | ||
| 462 | - case "300": | ||
| 463 | - case "301": | ||
| 464 | - progressDialogDismiss(); | ||
| 465 | - break; | ||
| 466 | - case "10000": | ||
| 467 | - ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 468 | - break; | ||
| 469 | - case "10001": | ||
| 470 | - ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 471 | - break; | ||
| 472 | - case "20000": | ||
| 473 | - isDefaultExit=false; | ||
| 474 | - showErrorDialog(); | ||
| 475 | - ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 476 | - break; | ||
| 477 | - } | ||
| 478 | - | ||
| 479 | - | ||
| 480 | - } | ||
| 481 | - | ||
| 482 | - @Override | ||
| 483 | - protected void onPause() { | ||
| 484 | - super.onPause(); | ||
| 485 | - xdySdk.onPlayStop(playVideoOrAudioId); | ||
| 486 | - if(isVideoMode){ | ||
| 487 | - stopVideo(); | ||
| 488 | - }else{ | ||
| 489 | - stopAudio(); | ||
| 490 | - } | ||
| 491 | - xdySdk.api("pauseRecordPlayback",""); | ||
| 492 | - } | ||
| 493 | - | ||
| 494 | - @Override | ||
| 495 | - protected void onResume() { | ||
| 496 | - super.onResume(); | ||
| 497 | - if (isVideoMode) { | ||
| 498 | - playVideo(playVideoOrAudioId); | ||
| 499 | - } else { | ||
| 500 | - playAudio(playVideoOrAudioId); | ||
| 501 | - } | ||
| 502 | - xdySdk.api("startRecordPlayback",""); | ||
| 503 | - } | ||
| 504 | - | ||
| 505 | - /** | ||
| 506 | - * 错误情况退出 | ||
| 507 | - */ | ||
| 508 | - public void exit() { | ||
| 509 | - xdySdk.api("stopPublishVideo",""); | ||
| 510 | - xdySdk.api("leaveClass", ""); | ||
| 511 | - xdySdk.remove(this); | ||
| 512 | - xdySdk.onPublisherStop(); | ||
| 513 | - if (mVideoView != null ){ | ||
| 514 | - mVideoView.stopPlayback(); | ||
| 515 | - } | ||
| 516 | - UIUtils.closeDialog(mLoginDialog); | ||
| 517 | - if(!replay) { | ||
| 518 | - xdySdk.removeAll(); | ||
| 519 | - } | ||
| 520 | - | ||
| 521 | - mmHandler.removeCallbacksAndMessages(null); | ||
| 522 | - this.finish(); | ||
| 523 | - } | ||
| 524 | - | ||
| 525 | - public void progressDialogDismiss() { | ||
| 526 | - if (mProgressDialog != null) { | ||
| 527 | - mProgressDialog.dismiss(); | ||
| 528 | - } | ||
| 529 | - } | ||
| 530 | - | ||
| 531 | - public void progressDialogShow() { | ||
| 532 | - if (mProgressDialog == null) { | ||
| 533 | - mProgressDialog = ProgressDialog.show(VideoPlayActivity.this, "", "加载中"); | ||
| 534 | - } else { | ||
| 535 | - mProgressDialog.show(); | ||
| 536 | - } | ||
| 537 | - } | ||
| 538 | - | ||
| 539 | - /** | ||
| 540 | - * 停止播放 | ||
| 541 | - * | ||
| 542 | - * @param response | ||
| 543 | - */ | ||
| 544 | - public void stopPlay(String response) { | ||
| 545 | - | ||
| 546 | - if(replay){ | ||
| 547 | - if(isVideoMode){ | ||
| 548 | - stopVideo(); | ||
| 549 | - }else{ | ||
| 550 | - stopAudio(); | ||
| 551 | - } | ||
| 552 | - }else{ | ||
| 553 | - VideoOrAudioStopEntity entity = JsonUtil.parseJsonToBean(response, VideoOrAudioStopEntity.class); | ||
| 554 | - if (entity != null) { | ||
| 555 | - if (xdySdk.onPlayStop(entity.getMediaId() + "")) { | ||
| 556 | - img_playVideo_novideo.setImageResource(R.mipmap.novideo); | ||
| 557 | - img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 558 | - } | ||
| 559 | - } | ||
| 560 | - } | ||
| 561 | - | ||
| 562 | - } | ||
| 563 | - public void showErrorDialog() { | ||
| 564 | - if(isDefaultExit){ | ||
| 565 | - return; | ||
| 566 | - } | ||
| 567 | - if (mErrorDialog != null) | ||
| 568 | - return; | ||
| 569 | - | ||
| 570 | - mErrorDialog = new AlertDialog.Builder(this) | ||
| 571 | - .setTitle("退出") | ||
| 572 | - .setMessage("您设备的网络属于断开状态,请重新进入") | ||
| 573 | - .setPositiveButton("确认", new DialogInterface.OnClickListener() { | ||
| 574 | - @Override | ||
| 575 | - public void onClick(DialogInterface dialogInterface, int i) { | ||
| 576 | - dialogInterface.dismiss(); | ||
| 577 | - exit(); | ||
| 578 | - | ||
| 579 | - } | ||
| 580 | - }) | ||
| 581 | - .create(); | ||
| 582 | - mErrorDialog.setCanceledOnTouchOutside(false); | ||
| 583 | - | ||
| 584 | - mErrorDialog.show(); | ||
| 585 | - | ||
| 586 | - } | ||
| 587 | - @Override | ||
| 588 | - public void observerUpData(String type, String parameter) { | ||
| 589 | - XdyLogUtil.e(TAG + "observer:", Thread.currentThread().getId() + "type:"+type); | ||
| 590 | - ResponseEntity responseEntity = new ResponseEntity(type, parameter); | ||
| 591 | - Message message = Message.obtain(); | ||
| 592 | - message.obj = responseEntity; | ||
| 593 | - mmHandler.sendMessage(message); | ||
| 594 | - } | ||
| 595 | - | ||
| 596 | - | ||
| 597 | - /******************************悬浮********************************/ | ||
| 598 | - /** | ||
| 599 | - * 窗口管理者 | ||
| 600 | - */ | ||
| 601 | - private WindowManager mWindowManager; | ||
| 602 | - | ||
| 603 | - // desk capture | ||
| 604 | - private int mScreenDensity; | ||
| 605 | - private int sreenWindowWidth; | ||
| 606 | - private int screenWindowHeight; | ||
| 607 | - private VirtualDisplay mVirtualDisplay; | ||
| 608 | - private MediaProjectionManager mMediaProjectionManager; | ||
| 609 | - private MediaProjection mMediaProjection; | ||
| 610 | - private SurfaceView bgSurfaceView; | ||
| 611 | - @SuppressWarnings("deprecation") | ||
| 612 | - @SuppressLint("NewApi") | ||
| 613 | - private void createScreenEnvironment() { | ||
| 614 | - sreenWindowWidth = mWindowManager.getDefaultDisplay().getWidth(); | ||
| 615 | - screenWindowHeight = mWindowManager.getDefaultDisplay().getHeight(); | ||
| 616 | - | ||
| 617 | -// if (sreenWindowWidth > 800) { | ||
| 618 | -// if (screenResolution == SCREEN_RESOLUTION_STANDARD) { | ||
| 619 | -// sreenWindowWidth = align(sreenWindowWidth / 2, 16); | ||
| 620 | -// screenWindowHeight = align(screenWindowHeight / 2, 16); | ||
| 621 | -// } else { | ||
| 622 | -// sreenWindowWidth = align(sreenWindowWidth * 2 / 5, 16); | ||
| 623 | -// screenWindowHeight = align(screenWindowHeight * 2 / 5, 16); | ||
| 624 | -// } | ||
| 625 | -// } | ||
| 626 | - | ||
| 627 | - Log.i(TAG, "mWindowWidth : " + sreenWindowWidth + ",mWindowHeight : " | ||
| 628 | - + screenWindowHeight); | ||
| 629 | - DisplayMetrics displayMetrics = new DisplayMetrics(); | ||
| 630 | - mWindowManager.getDefaultDisplay().getMetrics(displayMetrics); | ||
| 631 | - mScreenDensity = displayMetrics.densityDpi; | ||
| 632 | -// densityDpi mImageReader = ImageReader.newInstance(sreenWindowWidth, | ||
| 633 | -// screenWindowHeight, 0x1, 2); | ||
| 634 | - | ||
| 635 | - mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); | ||
| 636 | - } | ||
| 637 | - public void initSmall(){ | ||
| 638 | - | ||
| 639 | - mWindowManager = (WindowManager) getSystemService(Service.WINDOW_SERVICE); | ||
| 640 | - | ||
| 641 | -// if (pushType == PUSH_TYPE_CAMERA) { | ||
| 642 | -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | ||
| 643 | -// | Intent.FLAG_ACTIVITY_SINGLE_TOP); | ||
| 644 | -// PendingIntent contentIntent = PendingIntent.getActivity(this, | ||
| 645 | -// 0, intent, 0); | ||
| 646 | -// | ||
| 647 | -// Intent bIntent = new Intent(this, BackgroudService.class); | ||
| 648 | -// PendingIntent deleteIntent = PendingIntentnt.getService(this, 0, | ||
| 649 | -// bIntent, 0); | ||
| 650 | -// | ||
| 651 | -//// notification = new Notification.Builder(this) | ||
| 652 | -//// .setContentTitle("后台采集中。。").setAutoCancel(true) | ||
| 653 | -//// .setDeleteIntent(deleteIntent) | ||
| 654 | -//// .setContentIntent(contentIntent).build(); | ||
| 655 | -// | ||
| 656 | -//// startForeground(android.os.Process.myPid(), notification); | ||
| 657 | - | ||
| 658 | - bgSurfaceView = new SurfaceView(this); | ||
| 659 | - bgSurfaceView.setZOrderMediaOverlay(true); | ||
| 660 | - WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( | ||
| 661 | - 1, 1, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, | ||
| 662 | - WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, | ||
| 663 | - PixelFormat.TRANSLUCENT); | ||
| 664 | - layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; | ||
| 665 | - | ||
| 666 | - ImageView initPic = new ImageView(VideoPlayActivity.this); | ||
| 667 | - initPic.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); | ||
| 668 | - initPic.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||
| 669 | - initPic.setImageResource(R.mipmap.no_video); | ||
| 670 | - mWindowManager.addView(bgSurfaceView, layoutParams); | ||
| 671 | -// xdySdk.api("publishVideo", "", bgSurfaceView, VideoPlayActivity.this); | ||
| 672 | - | ||
| 673 | -// bgSurfaceView.getHolder().addCallback(this); | ||
| 674 | - | ||
| 675 | - | ||
| 676 | - } | ||
| 677 | - | ||
| 678 | - | ||
| 679 | - /*************************************** 回放***************************************************/ | ||
| 680 | - private static final int FADE_OUT = 1; | ||
| 681 | - private static final int SHOW_PROGRESS = 2; | ||
| 682 | - private boolean mShowing; | ||
| 683 | - private boolean mDragging; | ||
| 684 | - private RelativeLayout mMediaControllerRight; | ||
| 685 | -// @BindView(R.id.iv_operation_video) | ||
| 686 | -// ImageView operationIcon; | ||
| 687 | - // private PLMediaPlayer mMediaPlayer; | ||
| 688 | - @BindView(R.id.fl_media) | ||
| 689 | - FrameLayout mMediaContainer; | ||
| 690 | - @BindView(R.id.iv_operation_play) | ||
| 691 | - ImageButton mPauseButton; | ||
| 692 | - @BindView(R.id.sb_live) | ||
| 693 | - SeekBar mSeekBar; | ||
| 694 | - @BindView(R.id.rl_operation_play) | ||
| 695 | - RelativeLayout mPauseContainer; | ||
| 696 | - private TextView mClassName; | ||
| 697 | - @BindView(R.id.tv_end_time) | ||
| 698 | - TextView mEndTime; | ||
| 699 | - @BindView(R.id.tv_current_time) | ||
| 700 | - TextView mCurrentTime; | ||
| 701 | - @SuppressLint("HandlerLeak") | ||
| 702 | - private Handler mHandler = new Handler() { | ||
| 703 | - @Override | ||
| 704 | - public void handleMessage(Message msg) { | ||
| 705 | - switch (msg.what) { | ||
| 706 | - case FADE_OUT: | ||
| 707 | - hideMediaContainer(); | ||
| 708 | - break; | ||
| 709 | - case SHOW_PROGRESS: | ||
| 710 | - setProgress(); | ||
| 711 | - if (!mDragging && mShowing) { | ||
| 712 | - msg = obtainMessage(SHOW_PROGRESS); | ||
| 713 | - sendMessageDelayed(msg, 1000); | ||
| 714 | - updatePausePlay(); | ||
| 715 | - } | ||
| 716 | - break; | ||
| 717 | - } | ||
| 718 | - } | ||
| 719 | - }; | ||
| 720 | - public void initReplay() { | ||
| 721 | - mVideoView.setOnInfoListener(this); | ||
| 722 | - mVideoView.setOnErrorListener(this); | ||
| 723 | - mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener); | ||
| 724 | - mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT); | ||
| 725 | - AVOptions options = new AVOptions(); | ||
| 726 | - mSeekBar.setOnSeekBarChangeListener(mSeekListener); | ||
| 727 | - | ||
| 728 | - // 解码方式: | ||
| 729 | -// codec=AVOptions.MEDIA_CODEC_HW_DECODE,硬解 | ||
| 730 | -// codec=AVOptions.MEDIA_CODEC_SW_DECODE, 软解 | ||
| 731 | -// codec=AVOptions.MEDIA_CODEC_AUTO, 硬解优先,失败后自动切换到软解 | ||
| 732 | -// 默认值是:MEDIA_CODEC_SW_DECODE | ||
| 733 | - options.setInteger(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_AUTO); | ||
| 734 | - | ||
| 735 | -// 准备超时时间,包括创建资源、建立连接、请求码流等,单位是 ms | ||
| 736 | -// 默认值是:无 | ||
| 737 | - options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000); | ||
| 738 | - | ||
| 739 | -// 读取视频流超时时间,单位是 ms | ||
| 740 | -// 默认值是:10 * 1000 | ||
| 741 | - options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000); | ||
| 742 | - | ||
| 743 | -// 当前播放的是否为在线直播,如果是,则底层会有一些播放优化 | ||
| 744 | -// 默认值是:0为关闭 1为是 | ||
| 745 | - if (!replay) { | ||
| 746 | - options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1); | ||
| 747 | -// 是否开启"延时优化",只在在线直播流中有效 | ||
| 748 | -// 默认值是:0 | ||
| 749 | - options.setInteger(KEY_DELAY_OPTIMIZATION, 1); | ||
| 750 | - } else { | ||
| 751 | - XdyLogUtil.i(TAG, "回放设置AVOptions.KEY_LIVE_STREAMING, 0"); | ||
| 752 | - options.setInteger(AVOptions.KEY_LIVE_STREAMING, 0); | ||
| 753 | - } | ||
| 754 | -// 默认的缓存大小,单位是 ms | ||
| 755 | -// 默认值是:2000 | ||
| 756 | - options.setInteger(AVOptions.KEY_CACHE_BUFFER_DURATION, 300); | ||
| 757 | - | ||
| 758 | -// 最大的缓存大小,单位是 ms | ||
| 759 | -// 默认值是:4000 | ||
| 760 | - options.setInteger(AVOptions.KEY_MAX_CACHE_BUFFER_DURATION, 300); | ||
| 761 | -// 是否自动启动播放,如果设置为 1,则在调用 `prepareAsync` 或者 `setVideoPath` 之后自动启动播放,无需调用 `start()` | ||
| 762 | -// 默认值是:1 | ||
| 763 | - options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0); | ||
| 764 | - | ||
| 765 | -// 播放前最大探测流的字节数,单位是 byte | ||
| 766 | -// 默认值是:128 * 1024 | ||
| 767 | - options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024); | ||
| 768 | - options.setInteger(AVOptions.KEY_BUFFER_TIME, 300); | ||
| 769 | - | ||
| 770 | -// 请在开始播放之前配置 | ||
| 771 | - mVideoView.setAVOptions(options); | ||
| 772 | - | ||
| 773 | - | ||
| 774 | - mPauseContainer.setOnClickListener(new View.OnClickListener() { | ||
| 775 | - @Override | ||
| 776 | - public void onClick(View v) { | ||
| 777 | - //开启或暂停回放 | ||
| 778 | - boolean pause = getRecordStatus(); | ||
| 779 | - pauseAndStart(!pause); | ||
| 780 | - } | ||
| 781 | - }); | ||
| 782 | - } | ||
| 783 | - | ||
| 784 | - @Override | ||
| 785 | - public boolean onError(PLMediaPlayer plMediaPlayer, int i) { | ||
| 786 | - return false; | ||
| 787 | - } | ||
| 788 | - | ||
| 789 | - @Override | ||
| 790 | - public boolean onInfo(PLMediaPlayer plMediaPlayer, int i, int i1) { | ||
| 791 | -// boolean videoMode = mPresenter.isVideoMode(); | ||
| 792 | - | ||
| 793 | -// if (videoMode && PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START == i) { | ||
| 794 | -//// initPic.setVisibility(View.INVISIBLE); | ||
| 795 | -// } | ||
| 796 | - return false; | ||
| 797 | - } | ||
| 798 | - | ||
| 799 | - private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() { | ||
| 800 | - @Override | ||
| 801 | - public void onSeekComplete(PLMediaPlayer plMediaPlayer) { | ||
| 802 | - Log.d(TAG, "onSeekComplete !"); | ||
| 803 | - } | ||
| 804 | - }; | ||
| 805 | - | ||
| 806 | - public void resetSeekBar() { | ||
| 807 | - if (mSeekBar != null) { | ||
| 808 | - setProgress(); | ||
| 809 | - } | ||
| 810 | - } | ||
| 811 | - | ||
| 812 | - public void setCurrentTime(int currentTime) { | ||
| 813 | - this.currentTime = currentTime; | ||
| 814 | - } | ||
| 815 | - public void seekRecordPlay(long b) { | ||
| 816 | - //TODO 清除以前的数据 | ||
| 817 | -// chatView.clearChatHistory(); | ||
| 818 | -// docView.clear(); | ||
| 819 | - EventBus.getDefault().post("doc"); | ||
| 820 | - EventBus.getDefault().post("chat"); | ||
| 821 | - seekRecordPlayback(b); | ||
| 822 | - } | ||
| 823 | - private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { | ||
| 824 | - | ||
| 825 | - public void onStartTrackingTouch(SeekBar bar) { | ||
| 826 | - mDragging = true; | ||
| 827 | - showMediaContainer(TIME_OUT); | ||
| 828 | - mHandler.removeMessages(SHOW_PROGRESS); | ||
| 829 | - //停掉音视频 | ||
| 830 | - if (isVideoMode) | ||
| 831 | - stopVideo(); | ||
| 832 | - else | ||
| 833 | - stopAudio(); | ||
| 834 | - } | ||
| 835 | - | ||
| 836 | - public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { | ||
| 837 | - if (!fromuser) | ||
| 838 | - return; | ||
| 839 | - setCurrentTime(progress); | ||
| 840 | - String time = generateTime(progress); | ||
| 841 | - if (mCurrentTime != null) | ||
| 842 | - mCurrentTime.setText(time); | ||
| 843 | - } | ||
| 844 | - | ||
| 845 | - public void onStopTrackingTouch(SeekBar bar) { | ||
| 846 | - seekRecordPlay(bar.getProgress() == 0 ? 1 : bar.getProgress()); | ||
| 847 | - showMediaContainer(TIME_OUT); | ||
| 848 | - mHandler.removeMessages(SHOW_PROGRESS); | ||
| 849 | - mDragging = false; | ||
| 850 | - mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000); | ||
| 851 | - } | ||
| 852 | - }; | ||
| 853 | - | ||
| 854 | - int TIME_OUT = 3600; | ||
| 855 | - | ||
| 856 | - /** | ||
| 857 | - * @param timeout 单位秒 | ||
| 858 | - */ | ||
| 859 | - public void showMediaContainer(int timeout) { | ||
| 860 | - if (!mShowing) { | ||
| 861 | - if (mPauseContainer != null) { | ||
| 862 | - mPauseContainer.requestLayout(); | ||
| 863 | - mPauseContainer.requestFocus(); | ||
| 864 | - } | ||
| 865 | - | ||
| 866 | - | ||
| 867 | - mShowing = true; | ||
| 868 | - } | ||
| 869 | - updatePausePlay(); | ||
| 870 | - mHandler.sendEmptyMessage(SHOW_PROGRESS); | ||
| 871 | - mMediaContainer.setVisibility(View.VISIBLE); | ||
| 872 | - if (timeout != 0) { | ||
| 873 | - mHandler.removeMessages(FADE_OUT); | ||
| 874 | - mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), | ||
| 875 | - timeout); | ||
| 876 | - } | ||
| 877 | - } | ||
| 878 | - | ||
| 879 | - | ||
| 880 | - private void setProgress() { | ||
| 881 | - if (!mDragging) { | ||
| 882 | - if (mEndTime != null) | ||
| 883 | - mEndTime.setText(generateTime(seek)); | ||
| 884 | - if (mCurrentTime != null) { | ||
| 885 | - mCurrentTime.setText(generateTime(currentTime)); | ||
| 886 | - } | ||
| 887 | - if (mSeekBar != null) { | ||
| 888 | - mSeekBar.setProgress(currentTime); | ||
| 889 | - } | ||
| 890 | - } | ||
| 891 | - } | ||
| 892 | - | ||
| 893 | - private String generateTime(long currentTime) { | ||
| 894 | - int totalSeconds = (int) (currentTime); | ||
| 895 | - | ||
| 896 | - int seconds = totalSeconds % 60; | ||
| 897 | - int minutes = (totalSeconds / 60) % 60; | ||
| 898 | - int hours = totalSeconds / 3600; | ||
| 899 | - | ||
| 900 | - if (hours > 0) { | ||
| 901 | - return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, | ||
| 902 | - seconds).toString(); | ||
| 903 | - } else { | ||
| 904 | - return String.format(Locale.US, "%02d:%02d", minutes, seconds) | ||
| 905 | - .toString(); | ||
| 906 | - } | ||
| 907 | - } | ||
| 908 | - | ||
| 909 | - public void hideMediaContainer() { | ||
| 910 | - if (!mDragging && mShowing) { | ||
| 911 | - try { | ||
| 912 | - mHandler.removeMessages(SHOW_PROGRESS); | ||
| 913 | - mMediaContainer.setVisibility(View.GONE); | ||
| 914 | - } catch (IllegalArgumentException ex) { | ||
| 915 | - Log.d(TAG, "MediaController already removed"); | ||
| 916 | - } | ||
| 917 | - mShowing = false; | ||
| 918 | - } | ||
| 919 | - } | ||
| 920 | -private boolean pause=true; | ||
| 921 | - /** | ||
| 922 | - * 退出标记 | ||
| 923 | - */ | ||
| 924 | - private boolean quit; | ||
| 925 | - private boolean isOver; | ||
| 926 | - public void updatePausePlay() { | ||
| 927 | - if (pause) | ||
| 928 | - mPauseButton.setImageResource(R.mipmap.play); | ||
| 929 | - else | ||
| 930 | - mPauseButton.setImageResource(R.mipmap.stop); | ||
| 931 | - } | ||
| 932 | - | ||
| 933 | - | ||
| 934 | - private void handleRecord(String pa) { | ||
| 935 | - try { | ||
| 936 | - JSONObject jsonObject = new JSONObject(pa); | ||
| 937 | - int status = jsonObject.optInt("status"); | ||
| 938 | - switch (status) { | ||
| 939 | - case Constants.RECORD_READY: | ||
| 940 | - pause = true; | ||
| 941 | - isOver = false; | ||
| 942 | - break; | ||
| 943 | - case Constants.RECORD_PLAYING: | ||
| 944 | - pause = false; | ||
| 945 | - isOver = false; | ||
| 946 | - pauseOrStartEverything(); | ||
| 947 | - break; | ||
| 948 | - case Constants.RECORD_SEEK: | ||
| 949 | - isOver = false; | ||
| 950 | - pause = false; | ||
| 951 | -// int keyFrameSeek = jsonObject.optInt("keyFrameSeekTime"); | ||
| 952 | -// mRootView.seek(keyFrameSeek); | ||
| 953 | - break; | ||
| 954 | - case Constants.RECORD_STOP: | ||
| 955 | - pause = true; | ||
| 956 | -// //停止后 录制回放要进行初始化 | ||
| 957 | - if (!quit) {//回放结束了 | ||
| 958 | -// isOver = true; | ||
| 959 | -// if (currentTime < recordPlaybackMaxTime) | ||
| 960 | -// currentTime++; | ||
| 961 | -// xdySdk.api("initRecordPlayback", initClass); | ||
| 962 | -// int classId = AccountUtils.getUser().getClassId(); | ||
| 963 | -// mModel.initRecordPlayback(classId, portal, userRole, userId); | ||
| 964 | -// //停止视频 | ||
| 965 | - stopVideo(); | ||
| 966 | - currentTime = 0; | ||
| 967 | - resetSeekBar(); | ||
| 968 | -// docView.clear(); | ||
| 969 | -// chatView.clearChatHistory(); | ||
| 970 | -// currentPlayAudio = null; | ||
| 971 | -// currentPlayVideo = null; | ||
| 972 | - EventBus.getDefault().post("doc"); | ||
| 973 | - EventBus.getDefault().post("chat"); | ||
| 974 | - } | ||
| 975 | - break; | ||
| 976 | - case Constants.RECORD_PAUSE: | ||
| 977 | - isOver = false; | ||
| 978 | - pause = true; | ||
| 979 | - pauseOrStartEverything(); | ||
| 980 | - break; | ||
| 981 | - } | ||
| 982 | - updatePausePlay(); | ||
| 983 | - } catch (JSONException e) { | ||
| 984 | - e.printStackTrace(); | ||
| 985 | - } | ||
| 986 | - } | ||
| 987 | - long seek=0; | ||
| 988 | - int currentTime; | ||
| 989 | - /** | ||
| 990 | - * 录制回放初始化 seek长度等信息 | ||
| 991 | - */ | ||
| 992 | - public void initRecordSeek(String response){ | ||
| 993 | - | ||
| 994 | - JSONObject jsonObject = null; | ||
| 995 | - | ||
| 996 | - try { | ||
| 997 | - jsonObject = new JSONObject(response); | ||
| 998 | - seek = jsonObject.optLong("recordPlaybackMaxTime"); | ||
| 999 | - } catch (JSONException e) { | ||
| 1000 | - e.printStackTrace(); | ||
| 1001 | - } | ||
| 1002 | -// if (mVideoView.isPlaying()) { | ||
| 1003 | -// mVideoView.stopPlayback(); | ||
| 1004 | -// } | ||
| 1005 | -// if (replay && seek > 0) { | ||
| 1006 | -// mVideoView.seekTo(seek * 1000); | ||
| 1007 | - | ||
| 1008 | - setProgress(); | ||
| 1009 | -// | ||
| 1010 | - mHandler.postDelayed(new Runnable() { | ||
| 1011 | - @Override | ||
| 1012 | - public void run() { | ||
| 1013 | - xdySdk.api("startRecordPlayback", ""); | ||
| 1014 | - } | ||
| 1015 | - }, 200); | ||
| 1016 | - mVideoView.start(); | ||
| 1017 | - } | ||
| 1018 | - | ||
| 1019 | - private void handleTime(String pa) { | ||
| 1020 | - try { | ||
| 1021 | - JSONObject jsonObject = new JSONObject(pa); | ||
| 1022 | - | ||
| 1023 | - //防止时间超了 | ||
| 1024 | - currentTime = jsonObject.optInt("classTimestamp"); | ||
| 1025 | - boolean isRe = jsonObject.optBoolean("recordStatus"); | ||
| 1026 | - | ||
| 1027 | - | ||
| 1028 | - | ||
| 1029 | - } catch (JSONException e) { | ||
| 1030 | - e.printStackTrace(); | ||
| 1031 | - } | ||
| 1032 | - setProgress(); | ||
| 1033 | - } | ||
| 1034 | - | ||
| 1035 | -// public void setProcess(){ | ||
| 1036 | -// if (mEndTime != null) | ||
| 1037 | -// mEndTime.setText(generateTime(seek)); | ||
| 1038 | -// if (mCurrentTime != null) { | ||
| 1039 | -// mCurrentTime.setText(generateTime(currentTime)); | ||
| 1040 | -// } | ||
| 1041 | -// if (mSeekBar != null){ | ||
| 1042 | -//// mSeekBar.setProgress(generateTime(currentTime)); | ||
| 1043 | -// } | ||
| 1044 | -// } | ||
| 1045 | - | ||
| 1046 | - public boolean getRecordStatus() { | ||
| 1047 | - return pause; | ||
| 1048 | - } | ||
| 1049 | - public void pauseOrStartEverything() { | ||
| 1050 | - boolean isPause = getRecordStatus(); | ||
| 1051 | - if (isPause && mVideoView != null && mVideoView.isPlaying()) { | ||
| 1052 | - mVideoView.pause(); | ||
| 1053 | - XdyLogUtil.i(TAG, "视频停止"); | ||
| 1054 | - } else if (mVideoView != null) { | ||
| 1055 | - mVideoView.start(); | ||
| 1056 | - XdyLogUtil.i(TAG, "视频开始"); | ||
| 1057 | - } | ||
| 1058 | - } | ||
| 1059 | - /** | ||
| 1060 | - * 回放 播放 音视频 | ||
| 1061 | - * @param response | ||
| 1062 | - */ | ||
| 1063 | - public void playRecord(String response){ | ||
| 1064 | - String json_video= aCache.getAsString(response); | ||
| 1065 | - if(TextUtils.isEmpty(json_video)){ | ||
| 1066 | - ///给出相应的提示表示没有 这个id | ||
| 1067 | - XdyLogUtil.e(TAG,"Play Video Can not find this VideoId"); | ||
| 1068 | - return; | ||
| 1069 | - } | ||
| 1070 | - VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class); | ||
| 1071 | - if(videoPlayBean!=null){ | ||
| 1072 | - //回放不会出现Constants.PLAY_SUCCESS: | ||
| 1073 | - if(img_playVideo_novideo!=null) | ||
| 1074 | - img_playVideo_novideo.setVisibility(View.GONE); | ||
| 1075 | - if (mVideoView.isPlaying()) { | ||
| 1076 | - mVideoView.stopPlayback(); | ||
| 1077 | -// mVideoView.pause(); | ||
| 1078 | - } | ||
| 1079 | - mVideoView.setVideoPath(videoPlayBean.getReplay()); | ||
| 1080 | - //TODO 这个地方需要调整进度的话 | ||
| 1081 | - XdyLogUtil.e("播放精度哈哈哈哈哈",""+videoPlayBean.getSeek()); | ||
| 1082 | - if (replay && videoPlayBean.getSeek() > 0) { | ||
| 1083 | - | ||
| 1084 | - mVideoView.seekTo(videoPlayBean.getSeek() * 1000); | ||
| 1085 | - } | ||
| 1086 | - mVideoView.start(); | ||
| 1087 | - XdyLogUtil.e("录制回放播放视频的了",""+videoPlayBean.getReplay()); | ||
| 1088 | - } | ||
| 1089 | - } | ||
| 1090 | - | ||
| 1091 | - public void stopVideo() { | ||
| 1092 | - mHandler.post(new Runnable() { | ||
| 1093 | - @Override | ||
| 1094 | - public void run() { | ||
| 1095 | - img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 1096 | - img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 1097 | - } | ||
| 1098 | - }); | ||
| 1099 | - | ||
| 1100 | - | ||
| 1101 | - if (isVideoMode && mVideoView != null && mVideoView.isPlaying()) | ||
| 1102 | - mVideoView.stopPlayback(); | ||
| 1103 | - } | ||
| 1104 | - | ||
| 1105 | - public void stopAudio() { | ||
| 1106 | - img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 1107 | - img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 1108 | - | ||
| 1109 | - if (isVideoMode && mVideoView != null && mVideoView.isPlaying()) | ||
| 1110 | - mVideoView.stopPlayback(); | ||
| 1111 | - | ||
| 1112 | - } | ||
| 1113 | - | ||
| 1114 | - @Override | ||
| 1115 | - public void onClick() { | ||
| 1116 | - if (replay) { | ||
| 1117 | - | ||
| 1118 | - if (mMediaContainer.getVisibility() == View.VISIBLE) { | ||
| 1119 | - hideMediaContainer(); | ||
| 1120 | - } else { | ||
| 1121 | - showMediaContainer(TIME_OUT); | ||
| 1122 | - } | ||
| 1123 | - } | ||
| 1124 | - } | ||
| 1125 | - | ||
| 1126 | - public void pauseAndStart(boolean b) { | ||
| 1127 | - if (b) { | ||
| 1128 | - pauseRecordPlayback(); | ||
| 1129 | - } else { | ||
| 1130 | - startRecordPlayback(); | ||
| 1131 | - } | ||
| 1132 | - } | ||
| 1133 | - public void pauseRecordPlayback() { | ||
| 1134 | - xdySdk.api("pauseRecordPlayback",""); | ||
| 1135 | - } | ||
| 1136 | - | ||
| 1137 | - public void startRecordPlayback() { | ||
| 1138 | - xdySdk.api("startRecordPlayback",""); | ||
| 1139 | - } | ||
| 1140 | - public void seekRecordPlayback(long time) { | ||
| 1141 | - TimeEntity timeEntity=new TimeEntity(time); | ||
| 1142 | - xdySdk.api("seekRecordPlayback", new Gson().toJson(timeEntity)); | ||
| 1143 | - | ||
| 1144 | - } | ||
| 1145 | -} | 1 | +package com.mang.xdy.demo.activity; |
| 2 | +; | ||
| 3 | +import android.Manifest; | ||
| 4 | +import android.annotation.SuppressLint; | ||
| 5 | +import android.app.ProgressDialog; | ||
| 6 | +import android.content.DialogInterface; | ||
| 7 | +import android.content.pm.PackageManager; | ||
| 8 | +import android.os.Bundle; | ||
| 9 | +import android.os.Handler; | ||
| 10 | +import android.os.Message; | ||
| 11 | +import android.support.design.widget.TabLayout; | ||
| 12 | +import android.support.v4.app.ActivityCompat; | ||
| 13 | +import android.support.v4.content.PermissionChecker; | ||
| 14 | +import android.support.v7.app.AlertDialog; | ||
| 15 | +import android.support.v7.app.AppCompatActivity; | ||
| 16 | +import android.text.TextUtils; | ||
| 17 | +import android.util.Log; | ||
| 18 | +import android.view.SurfaceHolder; | ||
| 19 | +import android.view.SurfaceView; | ||
| 20 | +import android.view.View; | ||
| 21 | +import android.view.WindowManager; | ||
| 22 | +import android.widget.FrameLayout; | ||
| 23 | +import android.widget.ImageButton; | ||
| 24 | +import android.widget.ImageView; | ||
| 25 | +import android.widget.RelativeLayout; | ||
| 26 | +import android.widget.SeekBar; | ||
| 27 | +import android.widget.TextView; | ||
| 28 | +import android.widget.Toast; | ||
| 29 | + | ||
| 30 | +import com.google.gson.Gson; | ||
| 31 | +import com.mang.xdy.bean.VideoPlayBean; | ||
| 32 | +import com.mang.xdy.cache.ACache; | ||
| 33 | +import com.mang.xdy.common.Constants; | ||
| 34 | +import com.mang.xdy.core.SPUtil; | ||
| 35 | +import com.mang.xdy.core.XdySdk; | ||
| 36 | +import com.mang.xdy.demo.R; | ||
| 37 | +import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter; | ||
| 38 | +import com.mang.xdy.demo.bean.ErrorEntity; | ||
| 39 | +import com.mang.xdy.demo.bean.InitClassSuccessEntity; | ||
| 40 | +import com.mang.xdy.demo.bean.JoinClass; | ||
| 41 | +import com.mang.xdy.demo.bean.ResponseEntity; | ||
| 42 | +import com.mang.xdy.demo.bean.TimeEntity; | ||
| 43 | +import com.mang.xdy.demo.bean.VideoOrAudioStopEntity; | ||
| 44 | +import com.mang.xdy.demo.utils.JsonUtil; | ||
| 45 | +import com.mang.xdy.demo.utils.ToastUtil; | ||
| 46 | +import com.mang.xdy.demo.widget.dialog.LoginDialog; | ||
| 47 | +import com.mang.xdy.demo.widget.view.NoScrollViewPager; | ||
| 48 | +import com.mang.xdy.listener.ObserverListener; | ||
| 49 | +import com.mang.xdy.utils.UIUtils; | ||
| 50 | +import com.mang.xdy.utils.XdyLogUtil; | ||
| 51 | +import com.mang.xdy.utils.XdyStringUtils; | ||
| 52 | +import com.pili.pldroid.player.AVOptions; | ||
| 53 | +import com.pili.pldroid.player.PLMediaPlayer; | ||
| 54 | +import com.pili.pldroid.player.widget.PLVideoTextureView; | ||
| 55 | +import com.pili.pldroid.player.widget.PLVideoView; | ||
| 56 | +import org.greenrobot.eventbus.EventBus; | ||
| 57 | +import org.json.JSONException; | ||
| 58 | +import org.json.JSONObject; | ||
| 59 | + | ||
| 60 | +import java.util.ArrayList; | ||
| 61 | +import java.util.Locale; | ||
| 62 | + | ||
| 63 | +import butterknife.BindView; | ||
| 64 | +import butterknife.ButterKnife; | ||
| 65 | + | ||
| 66 | +import static com.pili.pldroid.player.AVOptions.KEY_DELAY_OPTIMIZATION; | ||
| 67 | + | ||
| 68 | +public class VideoPlayActivity extends AppCompatActivity implements ObserverListener, PLMediaPlayer.OnErrorListener, PLMediaPlayer.OnInfoListener,NoScrollViewPager.OnRplayTouchListener { | ||
| 69 | + private final static String TAG = "VideoPlayActivity"; | ||
| 70 | + @BindView(R.id.img_playVideo_novideo) | ||
| 71 | + ImageView img_playVideo_novideo; | ||
| 72 | + @BindView(R.id.img_videoPlay_start) | ||
| 73 | + ImageView img_videoPlay_start; | ||
| 74 | + private String username = ""; | ||
| 75 | + private String userpwd = ""; | ||
| 76 | + private SimpleFragmentPagerAdapter pagerAdapter; | ||
| 77 | + @BindView(R.id.viewpager) | ||
| 78 | + NoScrollViewPager viewPager; | ||
| 79 | + private TabLayout tabLayout; | ||
| 80 | + @BindView(R.id.surfaceview_playVideo) | ||
| 81 | + SurfaceView surfaceviewPlayVideo; | ||
| 82 | + @BindView(R.id.img_videoPlay_stopPublish) | ||
| 83 | + ImageView btn_videoPlay_stopPublish; | ||
| 84 | + @BindView(R.id.sur_plaVideo_publish) | ||
| 85 | + SurfaceView surfaceView_publish; | ||
| 86 | + private String initClass = ""; | ||
| 87 | + private XdySdk xdySdk; | ||
| 88 | + private LoginDialog mLoginDialog; | ||
| 89 | + private ProgressDialog mProgressDialog; | ||
| 90 | + @BindView(R.id.img_playVideo_replay) | ||
| 91 | + PLVideoTextureView mVideoView; | ||
| 92 | + private String playVideoOrAudioId=""; | ||
| 93 | + //视频模式还是音频模式 | ||
| 94 | + private boolean isVideoMode=true; | ||
| 95 | + /*mcu断开或者网络原因为false*/ | ||
| 96 | + private boolean isDefaultExit=true; | ||
| 97 | + private AlertDialog mErrorDialog; | ||
| 98 | + private ACache aCache; | ||
| 99 | + //是否是回放状态, | ||
| 100 | + private boolean replay = false; | ||
| 101 | + SurfaceHolder sh; | ||
| 102 | + @BindView(R.id.img_videoPlay_back) | ||
| 103 | + ImageView mImageView_Back; | ||
| 104 | + @BindView(R.id.tv_videoPlay_className) | ||
| 105 | + TextView mTextView_ClassName; | ||
| 106 | + /*课堂名字*/ | ||
| 107 | + private String className; | ||
| 108 | + private Handler mmHandler = new Handler() { | ||
| 109 | + @Override | ||
| 110 | + public void handleMessage(Message msg) { | ||
| 111 | + super.handleMessage(msg); | ||
| 112 | + ResponseEntity responseEntity = (ResponseEntity) msg.obj; | ||
| 113 | + switch (responseEntity.getType()) { | ||
| 114 | + case Constants.CLASS_EXIT: | ||
| 115 | + ToastUtil.showToast("退出课堂",VideoPlayActivity.this); | ||
| 116 | + progressDialogDismiss(); | ||
| 117 | + exit(); | ||
| 118 | + break; | ||
| 119 | + case Constants.ERROR_CODE: | ||
| 120 | + handError(responseEntity.getType(), responseEntity.getParam()); | ||
| 121 | + break; | ||
| 122 | + case Constants.CLASS_INIT_SUCCESS: | ||
| 123 | + String login = responseEntity.getParam(); | ||
| 124 | + parseJoinClass(login, true); | ||
| 125 | + ToastUtil.showToastshort("初始化课堂成功", VideoPlayActivity.this); | ||
| 126 | + break; | ||
| 127 | + case Constants.CLASS_JOIN_SUCCESS: | ||
| 128 | + //加入课堂成功 | ||
| 129 | + progressDialogDismiss(); | ||
| 130 | + UIUtils.closeDialog(mLoginDialog); | ||
| 131 | + ToastUtil.showToastshort("加入课堂成功", VideoPlayActivity.this); | ||
| 132 | + String userJson = responseEntity.getParam(); | ||
| 133 | + SPUtil.putString(VideoPlayActivity.this, Constants.CLASS_JOIN_SUCCESS, userJson); | ||
| 134 | + JSONObject jsonObject = null; | ||
| 135 | + | ||
| 136 | + try { | ||
| 137 | + jsonObject = new JSONObject(userJson); | ||
| 138 | + seek = jsonObject.optLong("recordPlaybackMaxTime"); | ||
| 139 | + className=jsonObject.optString("className"); | ||
| 140 | + } catch (JSONException e) { | ||
| 141 | + e.printStackTrace(); | ||
| 142 | + } | ||
| 143 | + if(!TextUtils.isEmpty(className)){ | ||
| 144 | + mTextView_ClassName.setText(className); | ||
| 145 | + } | ||
| 146 | + if(replay) { | ||
| 147 | + initRecordSeek(userJson); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + break; | ||
| 151 | + case Constants.VIDEO_PLAY: | ||
| 152 | + //播放视频 | ||
| 153 | + playVideoOrAudioId=responseEntity.getParam(); | ||
| 154 | + isVideoMode=true; | ||
| 155 | + playVideo(responseEntity.getParam()); | ||
| 156 | + break; | ||
| 157 | + case Constants.AUDIO_PLAY: | ||
| 158 | + //播放音频 | ||
| 159 | + isVideoMode=false; | ||
| 160 | + playVideoOrAudioId=responseEntity.getParam(); | ||
| 161 | + playAudio(responseEntity.getParam()); | ||
| 162 | + break; | ||
| 163 | + case Constants.VIDEO_STOP: | ||
| 164 | + //停止播放 | ||
| 165 | + case Constants.AUDIO_STOP: | ||
| 166 | + //停止播放 | ||
| 167 | + stopPlay(responseEntity.getParam()); | ||
| 168 | + break; | ||
| 169 | + case Constants.PLAY_SUCCESS: | ||
| 170 | + //自定义消息 播放视频音频都通过这个来判断 | ||
| 171 | + img_playVideo_novideo.setVisibility(View.GONE); | ||
| 172 | + break; | ||
| 173 | + case Constants.CLASS_UPDATE_TIMER: | ||
| 174 | + if(replay) | ||
| 175 | + handleTime(responseEntity.getParam()); | ||
| 176 | + break; | ||
| 177 | + case Constants.RECORD_PLAYBACK_UPDATE: | ||
| 178 | + handleRecord(responseEntity.getParam()); | ||
| 179 | + break; | ||
| 180 | + | ||
| 181 | + | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + }; | ||
| 185 | + | ||
| 186 | + @Override | ||
| 187 | + protected void onCreate(final Bundle savedInstanceState) { | ||
| 188 | + super.onCreate(savedInstanceState); | ||
| 189 | + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //屏幕常亮 | ||
| 190 | + setContentView(R.layout.activity_video_play); | ||
| 191 | + ButterKnife.bind(this); | ||
| 192 | + aCache=ACache.get(this); | ||
| 193 | + xdySdk = XdySdk.getXdyInstance(); | ||
| 194 | + xdySdk.add(this); | ||
| 195 | + init(); | ||
| 196 | + | ||
| 197 | + progressDialogShow(); | ||
| 198 | + setTablayout(); | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + public void init() { | ||
| 202 | + ArrayList<String> arrayList=getIntent().getStringArrayListExtra("init"); | ||
| 203 | + if(arrayList!=null&&arrayList.size()>1){ | ||
| 204 | + initClass= arrayList.get(0); | ||
| 205 | + if(TextUtils.isEmpty(arrayList.get(1))){ | ||
| 206 | + replay=true; | ||
| 207 | + }else { | ||
| 208 | + replay=false; | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + if(!replay){ | ||
| 213 | + mVideoView.setVisibility(View.GONE); | ||
| 214 | + mMediaContainer.setVisibility(View.GONE); | ||
| 215 | + img_videoPlay_start.setVisibility(View.VISIBLE); | ||
| 216 | +// btn_videoPlay_stopPublish.setVisibility(View.VISIBLE); | ||
| 217 | + }else{ | ||
| 218 | + surfaceviewPlayVideo.setVisibility(View.GONE); | ||
| 219 | + initReplay(); | ||
| 220 | + | ||
| 221 | + } | ||
| 222 | + if(!replay){ | ||
| 223 | + xdySdk.api("init", initClass); | ||
| 224 | + }else{ | ||
| 225 | + xdySdk.api("initRecordPlayback", initClass); | ||
| 226 | + } | ||
| 227 | + currentTime=0; | ||
| 228 | + btn_videoPlay_stopPublish.setOnClickListener(new View.OnClickListener() { | ||
| 229 | + @Override | ||
| 230 | + public void onClick(View v) { | ||
| 231 | + xdySdk.api("stopPublishVideo", ""); | ||
| 232 | + img_videoPlay_start.setEnabled(true); | ||
| 233 | + btn_videoPlay_stopPublish.setEnabled(false); | ||
| 234 | + btn_videoPlay_stopPublish.setVisibility(View.GONE); | ||
| 235 | + img_videoPlay_start.setVisibility(View.VISIBLE); | ||
| 236 | + surfaceView_publish.setVisibility(View.GONE); | ||
| 237 | + } | ||
| 238 | + }); | ||
| 239 | + | ||
| 240 | + img_videoPlay_start.setOnClickListener(new View.OnClickListener() { | ||
| 241 | + @Override | ||
| 242 | + public void onClick(View v) { | ||
| 243 | + btn_videoPlay_stopPublish.setVisibility(View.VISIBLE); | ||
| 244 | + img_videoPlay_start.setVisibility(View.GONE); | ||
| 245 | + surfaceView_publish.setVisibility(View.VISIBLE); | ||
| 246 | + img_videoPlay_start.setEnabled(false); | ||
| 247 | + btn_videoPlay_stopPublish.setEnabled(true); | ||
| 248 | + sh = surfaceView_publish.getHolder(); | ||
| 249 | + surfaceView_publish.setZOrderMediaOverlay(true); | ||
| 250 | + xdySdk.api("publishVideo", "", surfaceView_publish, VideoPlayActivity.this); | ||
| 251 | + isVideoMode=true; | ||
| 252 | + | ||
| 253 | + } | ||
| 254 | + }); | ||
| 255 | + mImageView_Back.setOnClickListener(new View.OnClickListener() { | ||
| 256 | + @Override | ||
| 257 | + public void onClick(View v) { | ||
| 258 | + exit_dialog(); | ||
| 259 | + } | ||
| 260 | + }); | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + public void setTablayout() { | ||
| 264 | + pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this,replay); | ||
| 265 | + viewPager.setAdapter(pagerAdapter); | ||
| 266 | + viewPager.setOnRplayTouchListener(this); | ||
| 267 | + tabLayout = (TabLayout) findViewById(R.id.sliding_tabs); | ||
| 268 | + tabLayout.setupWithViewPager(viewPager,false); | ||
| 269 | + tabLayout.setTabMode(TabLayout.MODE_FIXED); | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + //判断解析是否有密码 | ||
| 273 | + public void parseJoinClass(String rsponse, boolean isShowPwd) { | ||
| 274 | + InitClassSuccessEntity initClassSuccessEntity = JsonUtil.parseJsonToBean(rsponse, InitClassSuccessEntity.class); | ||
| 275 | + if (initClassSuccessEntity != null) { | ||
| 276 | + if (initClassSuccessEntity.isPasswordRequired()) { | ||
| 277 | + isShowPwd = true; | ||
| 278 | + } else { | ||
| 279 | + isShowPwd = false; | ||
| 280 | + userpwd = "123321"; | ||
| 281 | + } | ||
| 282 | + } | ||
| 283 | + if (mLoginDialog == null) { | ||
| 284 | + mLoginDialog = new LoginDialog(this, isShowPwd, null); | ||
| 285 | + mLoginDialog.show(); | ||
| 286 | + progressDialogDismiss(); | ||
| 287 | + mLoginDialog.setCanceledOnTouchOutside(false); | ||
| 288 | + final boolean finalIsShowPwd = isShowPwd; | ||
| 289 | + mLoginDialog.setBtnClick(new View.OnClickListener() { | ||
| 290 | + @Override | ||
| 291 | + public void onClick(View view) { | ||
| 292 | + String[] nameAndPwd = mLoginDialog.getNameAndPwd(); | ||
| 293 | + joinClass(nameAndPwd[0], nameAndPwd[1], finalIsShowPwd); | ||
| 294 | + progressDialogShow(); | ||
| 295 | + } | ||
| 296 | + }); | ||
| 297 | + } else if (mLoginDialog != null) { | ||
| 298 | + UIUtils.closeDialog(mLoginDialog); | ||
| 299 | + } | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + //加入课堂 | ||
| 303 | + public void joinClass(String username, String userpwd, boolean isShowPwd) { | ||
| 304 | + JoinClass joinClass = new JoinClass(); | ||
| 305 | + joinClass.setHasCamera(false); | ||
| 306 | + joinClass.setHasMicrophone(false); | ||
| 307 | + joinClass.setUserName(username); | ||
| 308 | + if (!isShowPwd) { | ||
| 309 | + joinClass.setPassword("123321"); | ||
| 310 | + } else { | ||
| 311 | + joinClass.setPassword(userpwd); | ||
| 312 | + } | ||
| 313 | + String temp = new Gson().toJson(joinClass); | ||
| 314 | + String jsonParmp = XdyStringUtils.stringToJson(temp, true); | ||
| 315 | + XdyLogUtil.e("加入课堂", jsonParmp); | ||
| 316 | + xdySdk.api("joinClass", jsonParmp); | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + /** | ||
| 320 | + * 播放视频 | ||
| 321 | + * | ||
| 322 | + * @param response | ||
| 323 | + */ | ||
| 324 | + public void playVideo(String response) { | ||
| 325 | + | ||
| 326 | + progressDialogDismiss(); | ||
| 327 | + | ||
| 328 | + if(replay){ | ||
| 329 | + playRecord(response); | ||
| 330 | + | ||
| 331 | + }else { | ||
| 332 | + if(!checkPermission()){ | ||
| 333 | + return; | ||
| 334 | + } | ||
| 335 | + xdySdk.api("playVideo", response + "", surfaceviewPlayVideo, VideoPlayActivity.this); | ||
| 336 | +// img_playVideo_novideo.setVisibility(View.GONE); | ||
| 337 | + img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 338 | + ToastUtil.showToastshort("视频播放初始化", VideoPlayActivity.this); | ||
| 339 | + } | ||
| 340 | + } | ||
| 341 | + /** | ||
| 342 | + * 播放音频 | ||
| 343 | + * | ||
| 344 | + * @param response | ||
| 345 | + */ | ||
| 346 | + public void playAudio(String response) { | ||
| 347 | + | ||
| 348 | + if(replay){ | ||
| 349 | + playRecord(response); | ||
| 350 | + img_playVideo_novideo.setImageResource(R.mipmap.audio_mode); | ||
| 351 | + img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 352 | + }else { | ||
| 353 | + if(!checkPermission()){ | ||
| 354 | + return; | ||
| 355 | + } | ||
| 356 | + xdySdk.api("playAudio", response, null, VideoPlayActivity.this); | ||
| 357 | + img_playVideo_novideo.setImageResource(R.mipmap.audio_mode); | ||
| 358 | + img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 359 | + ToastUtil.showToastshort("音频播放初始化", VideoPlayActivity.this); | ||
| 360 | + } | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + @Override | ||
| 364 | + public void onBackPressed() { | ||
| 365 | + exit_dialog(); | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + public void exit_dialog(){ | ||
| 369 | + final AlertDialog alertDialog = new AlertDialog.Builder(this) | ||
| 370 | + .setTitle("退出") | ||
| 371 | + .setMessage("是否离开课堂") | ||
| 372 | + .setNegativeButton("在看看", new DialogInterface.OnClickListener() { | ||
| 373 | + @Override | ||
| 374 | + public void onClick(DialogInterface dialogInterface, int i) { | ||
| 375 | + dialogInterface.dismiss(); | ||
| 376 | + } | ||
| 377 | + }) | ||
| 378 | + .setPositiveButton("确认", new DialogInterface.OnClickListener() { | ||
| 379 | + @Override | ||
| 380 | + public void onClick(DialogInterface dialogInterface, int i) { | ||
| 381 | + | ||
| 382 | + | ||
| 383 | + //如果收到class_exit 就执行,退出界面 | ||
| 384 | + UIUtils.closeDialog(mLoginDialog); | ||
| 385 | + exit(); | ||
| 386 | + } | ||
| 387 | + }) | ||
| 388 | + .create(); | ||
| 389 | + alertDialog.show(); | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + /** | ||
| 393 | + * 错误处理 | ||
| 394 | + * | ||
| 395 | + * @param errorId | ||
| 396 | + * @param errorMsg | ||
| 397 | + */ | ||
| 398 | + public void handError(String errorId, String errorMsg) { | ||
| 399 | + ErrorEntity errorEntity = JsonUtil.parseJsonToBean(errorMsg, ErrorEntity.class); | ||
| 400 | + if (errorEntity == null) { | ||
| 401 | + return; | ||
| 402 | + } | ||
| 403 | + switch (errorEntity.getCode() + "") { | ||
| 404 | + case "100": | ||
| 405 | + case "101": | ||
| 406 | + case "102": | ||
| 407 | + case "103": | ||
| 408 | + case "104": | ||
| 409 | + case "105": | ||
| 410 | + case "106": | ||
| 411 | + case "107": | ||
| 412 | + case "200": | ||
| 413 | + case "201": | ||
| 414 | + case "202": | ||
| 415 | + case "203": | ||
| 416 | + case "204": | ||
| 417 | + case "205": | ||
| 418 | + case "206": | ||
| 419 | + case "207": | ||
| 420 | + case "208": | ||
| 421 | + ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 422 | + exit(); | ||
| 423 | + break; | ||
| 424 | + case "300": | ||
| 425 | + case "301": | ||
| 426 | + progressDialogDismiss(); | ||
| 427 | + break; | ||
| 428 | + case "10000": | ||
| 429 | + ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 430 | + break; | ||
| 431 | + case "10001": | ||
| 432 | + ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 433 | + break; | ||
| 434 | + case "20000": | ||
| 435 | + isDefaultExit=false; | ||
| 436 | + showErrorDialog(); | ||
| 437 | + ToastUtil.showToastshort(errorEntity.getReson(), this); | ||
| 438 | + break; | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + @Override | ||
| 445 | + protected void onPause() { | ||
| 446 | + super.onPause(); | ||
| 447 | + xdySdk.onPlayStop(playVideoOrAudioId); | ||
| 448 | + if(isVideoMode){ | ||
| 449 | + stopVideo(); | ||
| 450 | + }else{ | ||
| 451 | + stopAudio(); | ||
| 452 | + } | ||
| 453 | + if(replay) { | ||
| 454 | + xdySdk.api("pauseRecordPlayback", ""); | ||
| 455 | + } | ||
| 456 | +// xdySdk.onPublisherPause(); | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + @Override | ||
| 460 | + protected void onResume() { | ||
| 461 | + super.onResume(); | ||
| 462 | + if (isVideoMode) { | ||
| 463 | + playVideo(playVideoOrAudioId); | ||
| 464 | + } else { | ||
| 465 | + playAudio(playVideoOrAudioId); | ||
| 466 | + } | ||
| 467 | + if(replay) { | ||
| 468 | + xdySdk.api("startRecordPlayback", ""); | ||
| 469 | + } | ||
| 470 | +// xdySdk.onPublisherResume(); | ||
| 471 | + } | ||
| 472 | + | ||
| 473 | + /** | ||
| 474 | + * 错误情况退出 | ||
| 475 | + */ | ||
| 476 | + public void exit() { | ||
| 477 | + xdySdk.api("stopPublishVideo",""); | ||
| 478 | + xdySdk.api("leaveClass", ""); | ||
| 479 | + xdySdk.remove(this); | ||
| 480 | + xdySdk.onPublisherStop(); | ||
| 481 | + if (mVideoView != null ){ | ||
| 482 | + mVideoView.stopPlayback(); | ||
| 483 | + } | ||
| 484 | + UIUtils.closeDialog(mLoginDialog); | ||
| 485 | + if(!replay) { | ||
| 486 | + xdySdk.removeAll(); | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + mmHandler.removeCallbacksAndMessages(null); | ||
| 490 | + this.finish(); | ||
| 491 | + } | ||
| 492 | + | ||
| 493 | + public void progressDialogDismiss() { | ||
| 494 | + if (mProgressDialog != null) { | ||
| 495 | + mProgressDialog.dismiss(); | ||
| 496 | + } | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + public void progressDialogShow() { | ||
| 500 | + if (mProgressDialog == null) { | ||
| 501 | + mProgressDialog = ProgressDialog.show(VideoPlayActivity.this, "", "加载中"); | ||
| 502 | + } else { | ||
| 503 | + mProgressDialog.show(); | ||
| 504 | + } | ||
| 505 | + } | ||
| 506 | + | ||
| 507 | + /** | ||
| 508 | + * 停止播放 | ||
| 509 | + * | ||
| 510 | + * @param response | ||
| 511 | + */ | ||
| 512 | + public void stopPlay(String response) { | ||
| 513 | + | ||
| 514 | + if(replay){ | ||
| 515 | + if(isVideoMode){ | ||
| 516 | + stopVideo(); | ||
| 517 | + }else{ | ||
| 518 | + stopAudio(); | ||
| 519 | + } | ||
| 520 | + }else{ | ||
| 521 | + VideoOrAudioStopEntity entity = JsonUtil.parseJsonToBean(response, VideoOrAudioStopEntity.class); | ||
| 522 | + if (entity != null) { | ||
| 523 | + if (xdySdk.onPlayStop(entity.getMediaId() + "")) { | ||
| 524 | + img_playVideo_novideo.setImageResource(R.mipmap.novideo); | ||
| 525 | + img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 526 | + } | ||
| 527 | + } | ||
| 528 | + } | ||
| 529 | + | ||
| 530 | + } | ||
| 531 | + public void showErrorDialog() { | ||
| 532 | + if(isDefaultExit){ | ||
| 533 | + return; | ||
| 534 | + } | ||
| 535 | + if (mErrorDialog != null) | ||
| 536 | + return; | ||
| 537 | + | ||
| 538 | + mErrorDialog = new AlertDialog.Builder(this) | ||
| 539 | + .setTitle("退出") | ||
| 540 | + .setMessage("您设备的网络属于断开状态,请重新进入") | ||
| 541 | + .setPositiveButton("确认", new DialogInterface.OnClickListener() { | ||
| 542 | + @Override | ||
| 543 | + public void onClick(DialogInterface dialogInterface, int i) { | ||
| 544 | + dialogInterface.dismiss(); | ||
| 545 | + exit(); | ||
| 546 | + | ||
| 547 | + } | ||
| 548 | + }) | ||
| 549 | + .create(); | ||
| 550 | + mErrorDialog.setCanceledOnTouchOutside(false); | ||
| 551 | + | ||
| 552 | + mErrorDialog.show(); | ||
| 553 | + | ||
| 554 | + } | ||
| 555 | + private boolean isCameraCheckFirst=true; | ||
| 556 | + private boolean isAudioCheckFirst=true; | ||
| 557 | + private boolean checkPermission() { | ||
| 558 | +// try { | ||
| 559 | +// int pRecordAudio = PermissionChecker.checkCallingOrSelfPermission(this, "android.permission.RECORD_AUDIO"); | ||
| 560 | +// int pCamera = PermissionChecker.checkCallingOrSelfPermission(this, "android.permission.CAMERA"); | ||
| 561 | +// if(pRecordAudio != PackageManager.PERMISSION_GRANTED) { | ||
| 562 | +// Log.e(TAG,"do not have AudioRecord permission, please check"); | ||
| 563 | +// Toast.makeText(this,"do not have AudioRecord permission, please check", Toast.LENGTH_LONG).show(); | ||
| 564 | +// if(isCameraCheckFirst){ | ||
| 565 | +// //settingPermission(); | ||
| 566 | +// isCameraCheckFirst=false; | ||
| 567 | +// } | ||
| 568 | +// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, | ||
| 569 | +// 1); | ||
| 570 | +// return false; | ||
| 571 | +// } | ||
| 572 | +// if(pCamera != PackageManager.PERMISSION_GRANTED) { | ||
| 573 | +// Log.e(TAG,"do not have CAMERA permission, please check"); | ||
| 574 | +// Toast.makeText(this,"do not have CAMERA permission, please check", Toast.LENGTH_LONG).show(); | ||
| 575 | +// if(isAudioCheckFirst){ | ||
| 576 | +// //settingPermission(); | ||
| 577 | +// isAudioCheckFirst=false; | ||
| 578 | +// } | ||
| 579 | +// return false; | ||
| 580 | +// | ||
| 581 | +// } | ||
| 582 | +// } catch (Exception e) { | ||
| 583 | +// e.printStackTrace(); | ||
| 584 | +// } | ||
| 585 | + return true; | ||
| 586 | + } | ||
| 587 | + @Override | ||
| 588 | + public void observerUpData(String type, String parameter) { | ||
| 589 | + XdyLogUtil.e(TAG + "observer:", Thread.currentThread().getId() + "type:"+type); | ||
| 590 | + ResponseEntity responseEntity = new ResponseEntity(type, parameter); | ||
| 591 | + Message message = Message.obtain(); | ||
| 592 | + message.obj = responseEntity; | ||
| 593 | + mmHandler.sendMessage(message); | ||
| 594 | + } | ||
| 595 | + | ||
| 596 | + | ||
| 597 | + /*************************************** 回放***************************************************/ | ||
| 598 | + private static final int FADE_OUT = 1; | ||
| 599 | + private static final int SHOW_PROGRESS = 2; | ||
| 600 | + private boolean mShowing; | ||
| 601 | + private boolean mDragging; | ||
| 602 | + private RelativeLayout mMediaControllerRight; | ||
| 603 | + | ||
| 604 | + private boolean pause=true; | ||
| 605 | + /** | ||
| 606 | + * 退出标记 | ||
| 607 | + */ | ||
| 608 | + private boolean quit; | ||
| 609 | + private boolean isOver; | ||
| 610 | + @BindView(R.id.fl_media) | ||
| 611 | + FrameLayout mMediaContainer; | ||
| 612 | + @BindView(R.id.iv_operation_play) | ||
| 613 | + ImageButton mPauseButton; | ||
| 614 | + @BindView(R.id.sb_live) | ||
| 615 | + SeekBar mSeekBar; | ||
| 616 | + @BindView(R.id.rl_operation_play) | ||
| 617 | + RelativeLayout mPauseContainer; | ||
| 618 | + private TextView mClassName; | ||
| 619 | + @BindView(R.id.tv_end_time) | ||
| 620 | + TextView mEndTime; | ||
| 621 | + @BindView(R.id.tv_current_time) | ||
| 622 | + TextView mCurrentTime; | ||
| 623 | + @SuppressLint("HandlerLeak") | ||
| 624 | + private Handler mHandler = new Handler() { | ||
| 625 | + @Override | ||
| 626 | + public void handleMessage(Message msg) { | ||
| 627 | + switch (msg.what) { | ||
| 628 | + case FADE_OUT: | ||
| 629 | + hideMediaContainer(); | ||
| 630 | + break; | ||
| 631 | + case SHOW_PROGRESS: | ||
| 632 | + setProgress(); | ||
| 633 | + if (!mDragging && mShowing) { | ||
| 634 | + msg = obtainMessage(SHOW_PROGRESS); | ||
| 635 | + sendMessageDelayed(msg, 1000); | ||
| 636 | + updatePausePlay(); | ||
| 637 | + } | ||
| 638 | + break; | ||
| 639 | + } | ||
| 640 | + } | ||
| 641 | + }; | ||
| 642 | + public void initReplay() { | ||
| 643 | + mVideoView.setOnInfoListener(this); | ||
| 644 | + mVideoView.setOnErrorListener(this); | ||
| 645 | + mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener); | ||
| 646 | + mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT); | ||
| 647 | + AVOptions options = new AVOptions(); | ||
| 648 | + mSeekBar.setOnSeekBarChangeListener(mSeekListener); | ||
| 649 | + | ||
| 650 | + // 解码方式: | ||
| 651 | +// codec=AVOptions.MEDIA_CODEC_HW_DECODE,硬解 | ||
| 652 | +// codec=AVOptions.MEDIA_CODEC_SW_DECODE, 软解 | ||
| 653 | +// codec=AVOptions.MEDIA_CODEC_AUTO, 硬解优先,失败后自动切换到软解 | ||
| 654 | +// 默认值是:MEDIA_CODEC_SW_DECODE | ||
| 655 | + options.setInteger(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_AUTO); | ||
| 656 | + | ||
| 657 | +// 准备超时时间,包括创建资源、建立连接、请求码流等,单位是 ms | ||
| 658 | +// 默认值是:无 | ||
| 659 | + options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000); | ||
| 660 | + | ||
| 661 | +// 读取视频流超时时间,单位是 ms | ||
| 662 | +// 默认值是:10 * 1000 | ||
| 663 | + options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000); | ||
| 664 | + | ||
| 665 | +// 当前播放的是否为在线直播,如果是,则底层会有一些播放优化 | ||
| 666 | +// 默认值是:0为关闭 1为是 | ||
| 667 | + if (!replay) { | ||
| 668 | + options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1); | ||
| 669 | +// 是否开启"延时优化",只在在线直播流中有效 | ||
| 670 | +// 默认值是:0 | ||
| 671 | + options.setInteger(KEY_DELAY_OPTIMIZATION, 1); | ||
| 672 | + } else { | ||
| 673 | + XdyLogUtil.i(TAG, "回放设置AVOptions.KEY_LIVE_STREAMING, 0"); | ||
| 674 | + options.setInteger(AVOptions.KEY_LIVE_STREAMING, 0); | ||
| 675 | + } | ||
| 676 | +// 默认的缓存大小,单位是 ms | ||
| 677 | +// 默认值是:2000 | ||
| 678 | + options.setInteger(AVOptions.KEY_CACHE_BUFFER_DURATION, 300); | ||
| 679 | + | ||
| 680 | +// 最大的缓存大小,单位是 ms | ||
| 681 | +// 默认值是:4000 | ||
| 682 | + options.setInteger(AVOptions.KEY_MAX_CACHE_BUFFER_DURATION, 300); | ||
| 683 | +// 是否自动启动播放,如果设置为 1,则在调用 `prepareAsync` 或者 `setVideoPath` 之后自动启动播放,无需调用 `start()` | ||
| 684 | +// 默认值是:1 | ||
| 685 | + options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0); | ||
| 686 | + | ||
| 687 | +// 播放前最大探测流的字节数,单位是 byte | ||
| 688 | +// 默认值是:128 * 1024 | ||
| 689 | + options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024); | ||
| 690 | + options.setInteger(AVOptions.KEY_BUFFER_TIME, 300); | ||
| 691 | + | ||
| 692 | +// 请在开始播放之前配置 | ||
| 693 | + mVideoView.setAVOptions(options); | ||
| 694 | + | ||
| 695 | + | ||
| 696 | + mPauseContainer.setOnClickListener(new View.OnClickListener() { | ||
| 697 | + @Override | ||
| 698 | + public void onClick(View v) { | ||
| 699 | + //开启或暂停回放 | ||
| 700 | + boolean pause = getRecordStatus(); | ||
| 701 | + pauseAndStart(!pause); | ||
| 702 | + } | ||
| 703 | + }); | ||
| 704 | + } | ||
| 705 | + | ||
| 706 | + @Override | ||
| 707 | + public boolean onError(PLMediaPlayer plMediaPlayer, int i) { | ||
| 708 | + return false; | ||
| 709 | + } | ||
| 710 | + | ||
| 711 | + @Override | ||
| 712 | + public boolean onInfo(PLMediaPlayer plMediaPlayer, int i, int i1) { | ||
| 713 | + return false; | ||
| 714 | + } | ||
| 715 | + | ||
| 716 | + private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() { | ||
| 717 | + @Override | ||
| 718 | + public void onSeekComplete(PLMediaPlayer plMediaPlayer) { | ||
| 719 | + Log.d(TAG, "onSeekComplete !"); | ||
| 720 | + } | ||
| 721 | + }; | ||
| 722 | + | ||
| 723 | + public void resetSeekBar() { | ||
| 724 | + if (mSeekBar != null) { | ||
| 725 | + setProgress(); | ||
| 726 | + } | ||
| 727 | + } | ||
| 728 | + | ||
| 729 | + public void setCurrentTime(int currentTime) { | ||
| 730 | + this.currentTime = currentTime; | ||
| 731 | + } | ||
| 732 | + public void seekRecordPlay(long b) { | ||
| 733 | + //TODO 清除以前的数据 | ||
| 734 | +// chatView.clearChatHistory(); | ||
| 735 | +// docView.clear(); | ||
| 736 | + EventBus.getDefault().post("doc"); | ||
| 737 | + EventBus.getDefault().post("chat"); | ||
| 738 | + seekRecordPlayback(b); | ||
| 739 | + } | ||
| 740 | + private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { | ||
| 741 | + | ||
| 742 | + public void onStartTrackingTouch(SeekBar bar) { | ||
| 743 | + mDragging = true; | ||
| 744 | + showMediaContainer(TIME_OUT); | ||
| 745 | + mHandler.removeMessages(SHOW_PROGRESS); | ||
| 746 | + //停掉音视频 | ||
| 747 | + if (isVideoMode) | ||
| 748 | + stopVideo(); | ||
| 749 | + else | ||
| 750 | + stopAudio(); | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { | ||
| 754 | + if (!fromuser) | ||
| 755 | + return; | ||
| 756 | + setCurrentTime(progress); | ||
| 757 | + String time = generateTime(progress); | ||
| 758 | + if (mCurrentTime != null) | ||
| 759 | + mCurrentTime.setText(time); | ||
| 760 | + } | ||
| 761 | + | ||
| 762 | + public void onStopTrackingTouch(SeekBar bar) { | ||
| 763 | + seekRecordPlay(bar.getProgress() == 0 ? 1 : bar.getProgress()); | ||
| 764 | + showMediaContainer(TIME_OUT); | ||
| 765 | + mHandler.removeMessages(SHOW_PROGRESS); | ||
| 766 | + mDragging = false; | ||
| 767 | + mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000); | ||
| 768 | + } | ||
| 769 | + }; | ||
| 770 | + | ||
| 771 | + int TIME_OUT = 3600; | ||
| 772 | + | ||
| 773 | + /** | ||
| 774 | + * @param timeout 单位秒 | ||
| 775 | + */ | ||
| 776 | + public void showMediaContainer(int timeout) { | ||
| 777 | + if (!mShowing) { | ||
| 778 | + if (mPauseContainer != null) { | ||
| 779 | + mPauseContainer.requestLayout(); | ||
| 780 | + mPauseContainer.requestFocus(); | ||
| 781 | + } | ||
| 782 | + | ||
| 783 | + | ||
| 784 | + mShowing = true; | ||
| 785 | + } | ||
| 786 | + updatePausePlay(); | ||
| 787 | + mHandler.sendEmptyMessage(SHOW_PROGRESS); | ||
| 788 | + mMediaContainer.setVisibility(View.VISIBLE); | ||
| 789 | + if (timeout != 0) { | ||
| 790 | + mHandler.removeMessages(FADE_OUT); | ||
| 791 | + mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), | ||
| 792 | + timeout); | ||
| 793 | + } | ||
| 794 | + } | ||
| 795 | + | ||
| 796 | + | ||
| 797 | + private void setProgress() { | ||
| 798 | + if (!mDragging) { | ||
| 799 | + if (mEndTime != null) | ||
| 800 | + mEndTime.setText(generateTime(seek)); | ||
| 801 | + if (mCurrentTime != null) { | ||
| 802 | + mCurrentTime.setText(generateTime(currentTime)); | ||
| 803 | + } | ||
| 804 | + if (mSeekBar != null) { | ||
| 805 | + mSeekBar.setProgress(currentTime); | ||
| 806 | + } | ||
| 807 | + } | ||
| 808 | + } | ||
| 809 | + | ||
| 810 | + private String generateTime(long currentTime) { | ||
| 811 | + int totalSeconds = (int) (currentTime); | ||
| 812 | + | ||
| 813 | + int seconds = totalSeconds % 60; | ||
| 814 | + int minutes = (totalSeconds / 60) % 60; | ||
| 815 | + int hours = totalSeconds / 3600; | ||
| 816 | + | ||
| 817 | + if (hours > 0) { | ||
| 818 | + return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, | ||
| 819 | + seconds).toString(); | ||
| 820 | + } else { | ||
| 821 | + return String.format(Locale.US, "%02d:%02d", minutes, seconds) | ||
| 822 | + .toString(); | ||
| 823 | + } | ||
| 824 | + } | ||
| 825 | + | ||
| 826 | + public void hideMediaContainer() { | ||
| 827 | + if (!mDragging && mShowing) { | ||
| 828 | + try { | ||
| 829 | + mHandler.removeMessages(SHOW_PROGRESS); | ||
| 830 | + mMediaContainer.setVisibility(View.GONE); | ||
| 831 | + } catch (IllegalArgumentException ex) { | ||
| 832 | + Log.d(TAG, "MediaController already removed"); | ||
| 833 | + } | ||
| 834 | + mShowing = false; | ||
| 835 | + } | ||
| 836 | + } | ||
| 837 | + public void updatePausePlay() { | ||
| 838 | + if (pause) | ||
| 839 | + mPauseButton.setImageResource(R.mipmap.play); | ||
| 840 | + else | ||
| 841 | + mPauseButton.setImageResource(R.mipmap.stop); | ||
| 842 | + } | ||
| 843 | + | ||
| 844 | + | ||
| 845 | + private void handleRecord(String pa) { | ||
| 846 | + try { | ||
| 847 | + JSONObject jsonObject = new JSONObject(pa); | ||
| 848 | + int status = jsonObject.optInt("status"); | ||
| 849 | + switch (status) { | ||
| 850 | + case Constants.RECORD_READY: | ||
| 851 | + pause = true; | ||
| 852 | + isOver = false; | ||
| 853 | + break; | ||
| 854 | + case Constants.RECORD_PLAYING: | ||
| 855 | + pause = false; | ||
| 856 | + isOver = false; | ||
| 857 | + pauseOrStartEverything(); | ||
| 858 | + break; | ||
| 859 | + case Constants.RECORD_SEEK: | ||
| 860 | + isOver = false; | ||
| 861 | + pause = false; | ||
| 862 | + break; | ||
| 863 | + case Constants.RECORD_STOP: | ||
| 864 | + pause = true; | ||
| 865 | +// //停止后 录制回放要进行初始化 | ||
| 866 | + if (!quit) {//回放结束了 | ||
| 867 | +// //停止视频 | ||
| 868 | + stopVideo(); | ||
| 869 | + currentTime = 0; | ||
| 870 | + resetSeekBar(); | ||
| 871 | + EventBus.getDefault().post("doc"); | ||
| 872 | + EventBus.getDefault().post("chat"); | ||
| 873 | + } | ||
| 874 | + break; | ||
| 875 | + case Constants.RECORD_PAUSE: | ||
| 876 | + isOver = false; | ||
| 877 | + pause = true; | ||
| 878 | + pauseOrStartEverything(); | ||
| 879 | + break; | ||
| 880 | + } | ||
| 881 | + updatePausePlay(); | ||
| 882 | + } catch (JSONException e) { | ||
| 883 | + e.printStackTrace(); | ||
| 884 | + } | ||
| 885 | + } | ||
| 886 | + long seek=0; | ||
| 887 | + int currentTime; | ||
| 888 | + /** | ||
| 889 | + * 录制回放初始化 seek长度等信息 | ||
| 890 | + */ | ||
| 891 | + public void initRecordSeek(String response){ | ||
| 892 | + | ||
| 893 | + setProgress(); | ||
| 894 | + mHandler.postDelayed(new Runnable() { | ||
| 895 | + @Override | ||
| 896 | + public void run() { | ||
| 897 | + xdySdk.api("startRecordPlayback", ""); | ||
| 898 | + } | ||
| 899 | + }, 200); | ||
| 900 | + mVideoView.start(); | ||
| 901 | + } | ||
| 902 | + | ||
| 903 | + private void handleTime(String pa) { | ||
| 904 | + try { | ||
| 905 | + JSONObject jsonObject = new JSONObject(pa); | ||
| 906 | + //防止时间超了 | ||
| 907 | + currentTime = jsonObject.optInt("classTimestamp"); | ||
| 908 | + boolean isRe = jsonObject.optBoolean("recordStatus"); | ||
| 909 | + | ||
| 910 | + } catch (JSONException e) { | ||
| 911 | + e.printStackTrace(); | ||
| 912 | + } | ||
| 913 | + setProgress(); | ||
| 914 | + } | ||
| 915 | + public boolean getRecordStatus() { | ||
| 916 | + return pause; | ||
| 917 | + } | ||
| 918 | + public void pauseOrStartEverything() { | ||
| 919 | + boolean isPause = getRecordStatus(); | ||
| 920 | + if (isPause && mVideoView != null && mVideoView.isPlaying()) { | ||
| 921 | + mVideoView.pause(); | ||
| 922 | + XdyLogUtil.i(TAG, "视频停止"); | ||
| 923 | + } else if (mVideoView != null) { | ||
| 924 | + mVideoView.start(); | ||
| 925 | + XdyLogUtil.i(TAG, "视频开始"); | ||
| 926 | + } | ||
| 927 | + } | ||
| 928 | + /** | ||
| 929 | + * 回放 播放 音视频 | ||
| 930 | + * @param response | ||
| 931 | + */ | ||
| 932 | + public void playRecord(String response){ | ||
| 933 | + String json_video= aCache.getAsString(response); | ||
| 934 | + if(TextUtils.isEmpty(json_video)){ | ||
| 935 | + ///给出相应的提示表示没有 这个id | ||
| 936 | + XdyLogUtil.e(TAG,"Play Video Can not find this VideoId"); | ||
| 937 | + return; | ||
| 938 | + } | ||
| 939 | + VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class); | ||
| 940 | + if(videoPlayBean!=null){ | ||
| 941 | + //回放不会出现Constants.PLAY_SUCCESS: | ||
| 942 | + if(img_playVideo_novideo!=null) | ||
| 943 | + img_playVideo_novideo.setVisibility(View.GONE); | ||
| 944 | + if (mVideoView.isPlaying()) { | ||
| 945 | + mVideoView.stopPlayback(); | ||
| 946 | + } | ||
| 947 | + mVideoView.setVideoPath(videoPlayBean.getReplay()); | ||
| 948 | + if (replay && videoPlayBean.getSeek() > 0) { | ||
| 949 | + | ||
| 950 | + mVideoView.seekTo(videoPlayBean.getSeek() * 1000); | ||
| 951 | + } | ||
| 952 | + mVideoView.start(); | ||
| 953 | + } | ||
| 954 | + } | ||
| 955 | + | ||
| 956 | + public void stopVideo() { | ||
| 957 | + mHandler.post(new Runnable() { | ||
| 958 | + @Override | ||
| 959 | + public void run() { | ||
| 960 | + img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 961 | + img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 962 | + } | ||
| 963 | + }); | ||
| 964 | + | ||
| 965 | + | ||
| 966 | + if (isVideoMode && mVideoView != null && mVideoView.isPlaying()) | ||
| 967 | + mVideoView.stopPlayback(); | ||
| 968 | + } | ||
| 969 | + | ||
| 970 | + public void stopAudio() { | ||
| 971 | + img_playVideo_novideo.setImageResource(R.mipmap.no_video); | ||
| 972 | + img_playVideo_novideo.setVisibility(View.VISIBLE); | ||
| 973 | + | ||
| 974 | + if (isVideoMode && mVideoView != null && mVideoView.isPlaying()) | ||
| 975 | + mVideoView.stopPlayback(); | ||
| 976 | + | ||
| 977 | + } | ||
| 978 | + | ||
| 979 | + @Override | ||
| 980 | + public void onClick() { | ||
| 981 | + if (replay) { | ||
| 982 | + | ||
| 983 | + if (mMediaContainer.getVisibility() == View.VISIBLE) { | ||
| 984 | + hideMediaContainer(); | ||
| 985 | + } else { | ||
| 986 | + showMediaContainer(TIME_OUT); | ||
| 987 | + } | ||
| 988 | + } | ||
| 989 | + } | ||
| 990 | + | ||
| 991 | + public void pauseAndStart(boolean b) { | ||
| 992 | + if (b) { | ||
| 993 | + pauseRecordPlayback(); | ||
| 994 | + } else { | ||
| 995 | + startRecordPlayback(); | ||
| 996 | + } | ||
| 997 | + } | ||
| 998 | + public void pauseRecordPlayback() { | ||
| 999 | + xdySdk.api("pauseRecordPlayback",""); | ||
| 1000 | + } | ||
| 1001 | + | ||
| 1002 | + public void startRecordPlayback() { | ||
| 1003 | + xdySdk.api("startRecordPlayback",""); | ||
| 1004 | + } | ||
| 1005 | + public void seekRecordPlayback(long time) { | ||
| 1006 | + TimeEntity timeEntity=new TimeEntity(time); | ||
| 1007 | + xdySdk.api("seekRecordPlayback", new Gson().toJson(timeEntity)); | ||
| 1008 | + } | ||
| 1009 | +} |
| 1 | -<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | - xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | - android:id="@+id/activity_main" | ||
| 5 | - android:layout_width="match_parent" | ||
| 6 | - android:layout_height="match_parent" | ||
| 7 | - android:orientation="vertical" | ||
| 8 | - tools:context="com.mang.xdy.demo.MainActivity"> | ||
| 9 | - <TextView | ||
| 10 | - android:layout_width="match_parent" | ||
| 11 | - android:layout_height="wrap_content" | ||
| 12 | - android:text="课堂Id" | ||
| 13 | - /> | ||
| 14 | - <EditText | ||
| 15 | - android:id="@+id/edt_home_classId" | ||
| 16 | - android:layout_width="match_parent" | ||
| 17 | - android:layout_height="wrap_content" | ||
| 18 | - android:hint="请输入课堂号" | ||
| 19 | - android:text="391813551"/> | ||
| 20 | - <TextView | ||
| 21 | - android:layout_width="match_parent" | ||
| 22 | - android:layout_height="wrap_content" | ||
| 23 | - android:text="角色"/> | ||
| 24 | - <EditText | ||
| 25 | - android:id="@+id/edt_home_role" | ||
| 26 | - android:layout_width="match_parent" | ||
| 27 | - android:layout_height="wrap_content" | ||
| 28 | - android:text="normal" | ||
| 29 | - /> | ||
| 30 | - <TextView | ||
| 31 | - | ||
| 32 | - android:layout_width="match_parent" | ||
| 33 | - android:layout_height="wrap_content" | ||
| 34 | - android:text="服务器地址" | ||
| 35 | - /> | ||
| 36 | - <EditText | ||
| 37 | - android:id="@+id/edt_home_serviceIp" | ||
| 38 | - android:layout_width="match_parent" | ||
| 39 | - android:layout_height="wrap_content" | ||
| 40 | - android:text="112.126.80.182:90" | ||
| 41 | - /> | ||
| 42 | - <TextView | ||
| 43 | - android:layout_width="match_parent" | ||
| 44 | - android:layout_height="wrap_content" | ||
| 45 | - android:text="用户id" | ||
| 46 | - /> | ||
| 47 | - <EditText | ||
| 48 | - android:id="@+id/edt_home_userId" | ||
| 49 | - android:layout_width="match_parent" | ||
| 50 | - android:layout_height="wrap_content" | ||
| 51 | - android:text="0" | ||
| 52 | - /> | ||
| 53 | - <Button | ||
| 54 | - android:id="@+id/btn_home_enter_class" | ||
| 55 | - android:layout_width="match_parent" | ||
| 56 | - android:layout_height="wrap_content" | ||
| 57 | - android:text="进入课堂" | ||
| 58 | - | ||
| 59 | - /> | ||
| 60 | - <Button | ||
| 61 | - android:id="@+id/btn_home_enter_publisher" | ||
| 62 | - android:layout_width="match_parent" | ||
| 63 | - android:layout_height="wrap_content" | ||
| 64 | - android:text="录制回放" | ||
| 65 | - /> | ||
| 66 | - | ||
| 67 | - <Button | ||
| 68 | - android:id="@+id/btn_home_enter_publisherAudio" | ||
| 69 | - android:layout_width="match_parent" | ||
| 70 | - android:layout_height="wrap_content" | ||
| 71 | - android:text="推音频" | ||
| 72 | - android:visibility="gone" | ||
| 73 | - /> | ||
| 74 | -</LinearLayout> | 1 | +<?xml version="1.0" encoding="utf-8"?> |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | + android:id="@+id/activity_main" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:orientation="vertical" | ||
| 8 | + tools:context="com.mang.xdy.demo.MainActivity"> | ||
| 9 | + <TextView | ||
| 10 | + android:layout_width="match_parent" | ||
| 11 | + android:layout_height="wrap_content" | ||
| 12 | + android:text="课堂Id" | ||
| 13 | + /> | ||
| 14 | + <EditText | ||
| 15 | + android:id="@+id/edt_home_classId" | ||
| 16 | + android:layout_width="match_parent" | ||
| 17 | + android:layout_height="wrap_content" | ||
| 18 | + android:hint="请输入课堂号" | ||
| 19 | + android:text="1332699420"/> | ||
| 20 | + <TextView | ||
| 21 | + android:layout_width="match_parent" | ||
| 22 | + android:layout_height="wrap_content" | ||
| 23 | + android:text="角色"/> | ||
| 24 | + <EditText | ||
| 25 | + android:id="@+id/edt_home_role" | ||
| 26 | + android:layout_width="match_parent" | ||
| 27 | + android:layout_height="wrap_content" | ||
| 28 | + android:text="normal" | ||
| 29 | + /> | ||
| 30 | + <TextView | ||
| 31 | + | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="wrap_content" | ||
| 34 | + android:text="服务器地址" | ||
| 35 | + /> | ||
| 36 | + <EditText | ||
| 37 | + android:id="@+id/edt_home_serviceIp" | ||
| 38 | + android:layout_width="match_parent" | ||
| 39 | + android:layout_height="wrap_content" | ||
| 40 | + android:text="112.126.80.182:90" | ||
| 41 | + /> | ||
| 42 | + <TextView | ||
| 43 | + android:layout_width="match_parent" | ||
| 44 | + android:layout_height="wrap_content" | ||
| 45 | + android:text="用户id" | ||
| 46 | + /> | ||
| 47 | + <EditText | ||
| 48 | + android:id="@+id/edt_home_userId" | ||
| 49 | + android:layout_width="match_parent" | ||
| 50 | + android:layout_height="wrap_content" | ||
| 51 | + android:text="0" | ||
| 52 | + /> | ||
| 53 | + <Button | ||
| 54 | + android:id="@+id/btn_home_enter_class" | ||
| 55 | + android:layout_width="match_parent" | ||
| 56 | + android:layout_height="wrap_content" | ||
| 57 | + android:text="进入课堂" | ||
| 58 | + | ||
| 59 | + /> | ||
| 60 | + <Button | ||
| 61 | + android:id="@+id/btn_home_enter_publisher" | ||
| 62 | + android:layout_width="match_parent" | ||
| 63 | + android:layout_height="wrap_content" | ||
| 64 | + android:text="录制回放" | ||
| 65 | + /> | ||
| 66 | + | ||
| 67 | +</LinearLayout> |
| 1 | -<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | - xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | - android:id="@+id/activity_video_play" | ||
| 5 | - android:layout_width="match_parent" | ||
| 6 | - android:layout_height="match_parent" | ||
| 7 | - android:orientation="vertical" | ||
| 8 | - tools:context="com.mang.xdy.demo.activity.VideoPlayActivity"> | ||
| 9 | - | ||
| 10 | - <FrameLayout | ||
| 11 | - android:id="@+id/fl_videoview_container" | ||
| 12 | - android:layout_width="match_parent" | ||
| 13 | - android:layout_height="1dp" | ||
| 14 | - android:visibility="gone"> | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - </FrameLayout> | ||
| 18 | - <RelativeLayout | ||
| 19 | - android:layout_width="match_parent" | ||
| 20 | - android:layout_height="@dimen/ui_DIMEN_500.0PX"> | ||
| 21 | - <com.pili.pldroid.player.widget.PLVideoTextureView | ||
| 22 | - android:id="@+id/img_playVideo_replay" | ||
| 23 | - android:layout_width="match_parent" | ||
| 24 | - android:layout_height="match_parent" | ||
| 25 | - android:layout_gravity="center"/> | ||
| 26 | - <SurfaceView | ||
| 27 | - android:id="@+id/surfaceview_playVideo" | ||
| 28 | - android:layout_width="match_parent" | ||
| 29 | - android:layout_height="match_parent" | ||
| 30 | - /> | ||
| 31 | - <!--<FrameLayout--> | ||
| 32 | - <!--android:layout_width="match_parent"--> | ||
| 33 | - <!--android:layout_height="match_parent">--> | ||
| 34 | - | ||
| 35 | - <ImageView | ||
| 36 | - android:id="@+id/img_playVideo_novideo" | ||
| 37 | - android:layout_width="match_parent" | ||
| 38 | - android:layout_height="match_parent" | ||
| 39 | - android:background="@mipmap/novideo" | ||
| 40 | - /> | ||
| 41 | - <FrameLayout | ||
| 42 | - android:layout_width="wrap_content" | ||
| 43 | - android:layout_height="wrap_content"> | ||
| 44 | - <FrameLayout | ||
| 45 | - android:id="@+id/fra_videoPlay_publish" | ||
| 46 | - android:layout_width="150dp" | ||
| 47 | - android:layout_gravity="right|bottom" | ||
| 48 | - android:layout_height="100dp"> | ||
| 49 | - <Button | ||
| 50 | - android:id="@+id/btn_videoPlay_exit" | ||
| 51 | - android:layout_width="wrap_content" | ||
| 52 | - android:layout_height="wrap_content" | ||
| 53 | - android:text="开始推流" | ||
| 54 | - android:visibility="gone" | ||
| 55 | - | ||
| 56 | - /> | ||
| 57 | - </FrameLayout> | ||
| 58 | - | ||
| 59 | - </FrameLayout> | ||
| 60 | - | ||
| 61 | - </RelativeLayout> | ||
| 62 | - <SurfaceView | ||
| 63 | - android:id="@+id/surfaceview_playVideo_text" | ||
| 64 | - android:layout_width="150dp" | ||
| 65 | - android:layout_height="200dp" | ||
| 66 | - android:visibility="gone"/> | ||
| 67 | - <FrameLayout | ||
| 68 | - android:layout_width="wrap_content" | ||
| 69 | - android:layout_height="wrap_content"> | ||
| 70 | - <Button | ||
| 71 | - android:id="@+id/btn_videoPlay_stopPublish" | ||
| 72 | - android:layout_width="wrap_content" | ||
| 73 | - android:layout_height="wrap_content" | ||
| 74 | - android:text="结束按钮" | ||
| 75 | - android:visibility="gone" | ||
| 76 | - /> | ||
| 77 | - </FrameLayout> | ||
| 78 | - <android.support.design.widget.TabLayout | ||
| 79 | - android:id="@+id/sliding_tabs" | ||
| 80 | - android:layout_width="match_parent" | ||
| 81 | - android:layout_height="wrap_content" | ||
| 82 | - /> | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - <!--</FrameLayout>--> | ||
| 86 | - | ||
| 87 | - <com.mang.xdy.demo.widget.view.NoScrollViewPager | ||
| 88 | - android:id="@+id/viewpager" | ||
| 89 | - android:layout_width="match_parent" | ||
| 90 | - android:layout_height="0px" | ||
| 91 | - android:layout_weight="1" | ||
| 92 | - android:background="@android:color/white" /> | ||
| 93 | - <FrameLayout | ||
| 94 | - android:id="@+id/fl_media" | ||
| 95 | - android:layout_width="match_parent" | ||
| 96 | - android:layout_height="wrap_content" | ||
| 97 | - android:layout_alignParentBottom="true" | ||
| 98 | - > | ||
| 99 | - | ||
| 100 | - <include | ||
| 101 | - layout="@layout/home_media_controller" | ||
| 102 | - android:layout_width="match_parent" | ||
| 103 | - android:layout_height="wrap_content"/> | ||
| 104 | - </FrameLayout> | ||
| 105 | -</LinearLayout> | 1 | +<?xml version="1.0" encoding="utf-8"?> |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 4 | + android:id="@+id/activity_video_play" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:orientation="vertical" | ||
| 8 | + tools:context="com.mang.xdy.demo.activity.VideoPlayActivity"> | ||
| 9 | + <RelativeLayout | ||
| 10 | + android:layout_width="match_parent" | ||
| 11 | + android:layout_height="@dimen/ui_DIMEN_500.0PX"> | ||
| 12 | + <com.pili.pldroid.player.widget.PLVideoTextureView | ||
| 13 | + android:id="@+id/img_playVideo_replay" | ||
| 14 | + android:layout_width="match_parent" | ||
| 15 | + android:layout_height="match_parent" | ||
| 16 | + android:layout_gravity="center"/> | ||
| 17 | + <SurfaceView | ||
| 18 | + android:id="@+id/surfaceview_playVideo" | ||
| 19 | + android:layout_width="match_parent" | ||
| 20 | + android:layout_height="match_parent" | ||
| 21 | + /> | ||
| 22 | + android:layout_width="match_parent" | ||
| 23 | + android:layout_height="match_parent"> | ||
| 24 | + <ImageView | ||
| 25 | + android:id="@+id/img_playVideo_novideo" | ||
| 26 | + android:layout_width="match_parent" | ||
| 27 | + android:layout_height="match_parent" | ||
| 28 | + android:background="@mipmap/novideo" | ||
| 29 | + /> | ||
| 30 | + <FrameLayout | ||
| 31 | + android:layout_width="match_parent" | ||
| 32 | + android:layout_height="wrap_content"> | ||
| 33 | + | ||
| 34 | + </FrameLayout> | ||
| 35 | + <LinearLayout | ||
| 36 | + android:layout_width="wrap_content" | ||
| 37 | + android:layout_height="wrap_content" | ||
| 38 | + android:orientation="vertical" | ||
| 39 | + android:layout_alignParentRight="true" | ||
| 40 | + android:id="@+id/linearLayout"> | ||
| 41 | + | ||
| 42 | + </LinearLayout> | ||
| 43 | + <RelativeLayout | ||
| 44 | + android:layout_width="wrap_content" | ||
| 45 | + android:layout_height="wrap_content" | ||
| 46 | + android:layout_alignParentRight="true" | ||
| 47 | + android:layout_alignParentBottom="true" | ||
| 48 | + android:layout_below="@+id/linearLayout" | ||
| 49 | + android:layout_alignParentLeft="true" | ||
| 50 | + android:layout_alignParentStart="true"> | ||
| 51 | + <RelativeLayout | ||
| 52 | + android:id="@+id/avg_videoPlay_back" | ||
| 53 | + android:layout_width="match_parent" | ||
| 54 | + android:layout_height="wrap_content" | ||
| 55 | + android:layout_alignParentLeft="true" | ||
| 56 | + android:layout_alignParentStart="true" | ||
| 57 | + android:layout_alignParentTop="true" | ||
| 58 | + android:paddingLeft="@dimen/ui_DIMEN_20.0PX" | ||
| 59 | + android:paddingRight="@dimen/ui_DIMEN_20.0PX"> | ||
| 60 | + | ||
| 61 | + <ImageView | ||
| 62 | + android:id="@+id/img_videoPlay_back" | ||
| 63 | + android:layout_width="wrap_content" | ||
| 64 | + android:layout_height="@dimen/ui_titlebar_height" | ||
| 65 | + android:paddingRight="20dp" | ||
| 66 | + android:paddingLeft="15dp" | ||
| 67 | + android:src="@mipmap/back"/> | ||
| 68 | + <TextView | ||
| 69 | + android:id="@+id/tv_videoPlay_className" | ||
| 70 | + style="@style/ui_wrapTvBaseStyle" | ||
| 71 | + android:layout_height="@dimen/ui_titlebar_height" | ||
| 72 | + android:layout_centerHorizontal="true" | ||
| 73 | + android:gravity="center" | ||
| 74 | + android:textColor="@color/white" | ||
| 75 | + tools:text="hahaha" | ||
| 76 | + android:textSize="@dimen/ui_DIMEN_34.0PX"/> | ||
| 77 | + </RelativeLayout> | ||
| 78 | + <SurfaceView | ||
| 79 | + android:id="@+id/sur_plaVideo_publish" | ||
| 80 | + android:layout_width="120dp" | ||
| 81 | + android:layout_height="150dp" | ||
| 82 | + android:visibility="gone" | ||
| 83 | + tools:visibility="visible" | ||
| 84 | + android:layout_alignParentRight="true" | ||
| 85 | + android:layout_alignParentBottom="true" | ||
| 86 | + /> | ||
| 87 | + | ||
| 88 | + <ImageView | ||
| 89 | + android:id="@+id/img_videoPlay_start" | ||
| 90 | + android:layout_width="wrap_content" | ||
| 91 | + android:layout_height="wrap_content" | ||
| 92 | + android:layout_marginRight="25dp" | ||
| 93 | + android:layout_marginBottom="20dp" | ||
| 94 | + android:visibility="gone" | ||
| 95 | + tools:visibility="visible" | ||
| 96 | + android:layout_alignParentRight="true" | ||
| 97 | + android:layout_alignParentBottom="true" | ||
| 98 | + android:background="@mipmap/camerap_normal2x" | ||
| 99 | + /> | ||
| 100 | + <ImageView | ||
| 101 | + android:id="@+id/img_videoPlay_stopPublish" | ||
| 102 | + android:layout_width="wrap_content" | ||
| 103 | + android:layout_height="wrap_content" | ||
| 104 | + android:layout_alignBottom="@+id/sur_plaVideo_publish" | ||
| 105 | + android:enabled="false" | ||
| 106 | + android:background="@mipmap/hangup_normal2x" | ||
| 107 | + android:visibility="gone" | ||
| 108 | + android:layout_marginRight="25dp" | ||
| 109 | + android:layout_marginBottom="20dp" | ||
| 110 | + tools:visibility="visible" | ||
| 111 | + android:layout_alignParentRight="true" | ||
| 112 | + /> | ||
| 113 | + </RelativeLayout> | ||
| 114 | + </RelativeLayout> | ||
| 115 | + <SurfaceView | ||
| 116 | + android:id="@+id/surfaceview_playVideo_text" | ||
| 117 | + android:layout_width="150dp" | ||
| 118 | + android:layout_height="200dp" | ||
| 119 | + android:visibility="gone"/> | ||
| 120 | + <FrameLayout | ||
| 121 | + android:layout_width="wrap_content" | ||
| 122 | + android:layout_height="wrap_content" | ||
| 123 | + android:orientation="horizontal" | ||
| 124 | + > | ||
| 125 | + </FrameLayout> | ||
| 126 | + <android.support.design.widget.TabLayout | ||
| 127 | + android:id="@+id/sliding_tabs" | ||
| 128 | + android:layout_width="match_parent" | ||
| 129 | + android:layout_height="wrap_content" | ||
| 130 | + /> | ||
| 131 | + <com.mang.xdy.demo.widget.view.NoScrollViewPager | ||
| 132 | + android:id="@+id/viewpager" | ||
| 133 | + android:layout_width="match_parent" | ||
| 134 | + android:layout_height="0px" | ||
| 135 | + android:layout_weight="1" | ||
| 136 | + android:background="@android:color/white" /> | ||
| 137 | + <FrameLayout | ||
| 138 | + android:id="@+id/fl_media" | ||
| 139 | + android:layout_width="match_parent" | ||
| 140 | + android:layout_height="wrap_content" | ||
| 141 | + android:layout_alignParentBottom="true" | ||
| 142 | + > | ||
| 143 | + <include | ||
| 144 | + layout="@layout/home_media_controller" | ||
| 145 | + android:layout_width="match_parent" | ||
| 146 | + android:layout_height="wrap_content"/> | ||
| 147 | + </FrameLayout> | ||
| 148 | +</LinearLayout> |
| @@ -41,8 +41,6 @@ | @@ -41,8 +41,6 @@ | ||
| 41 | android:gravity="end" | 41 | android:gravity="end" |
| 42 | tools:text="12:00:12"/> | 42 | tools:text="12:00:12"/> |
| 43 | 43 | ||
| 44 | - | ||
| 45 | - | ||
| 46 | <TextView | 44 | <TextView |
| 47 | android:id="@+id/tv_end_time" | 45 | android:id="@+id/tv_end_time" |
| 48 | style="@style/ui_wrapTvBaseStyle" | 46 | style="@style/ui_wrapTvBaseStyle" |
| @@ -51,7 +49,6 @@ | @@ -51,7 +49,6 @@ | ||
| 51 | android:textColor="@color/white" | 49 | android:textColor="@color/white" |
| 52 | tools:text="12:00"/> | 50 | tools:text="12:00"/> |
| 53 | 51 | ||
| 54 | - | ||
| 55 | <SeekBar | 52 | <SeekBar |
| 56 | android:id="@+id/sb_live" | 53 | android:id="@+id/sb_live" |
| 57 | style="@style/home_seek_bar" | 54 | style="@style/home_seek_bar" |
| 1 | -//package com.mang.xdy.api; | ||
| 2 | -// | ||
| 3 | -//import android.content.Context; | ||
| 4 | -// | ||
| 5 | -// | ||
| 6 | -//import com.mang.xdy.common.Constants; | ||
| 7 | -//import com.mang.xdy.core.XdyCore; | ||
| 8 | -//import com.mang.xdy.utils.XdyLogUtil; | ||
| 9 | -// | ||
| 10 | -///** | ||
| 11 | -// * 对外调用的接口 | ||
| 12 | -// * Created by abao on 2017/3/31. | ||
| 13 | -// */ | ||
| 14 | -//public class XdyInterface { | ||
| 15 | -// /** | ||
| 16 | -// * 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件 | ||
| 17 | -// */ | ||
| 18 | -// private static XdyCore mXdyCore; | ||
| 19 | -// private static XdyInterface mXdyInterface; | ||
| 20 | -// | ||
| 21 | -// /** | ||
| 22 | -// * 对外提供的异步消息接收接口(可以多个吗?) | ||
| 23 | -// */ | ||
| 24 | -// public interface OnXdyAsyncMessageLitener{ | ||
| 25 | -// /** | ||
| 26 | -// * | ||
| 27 | -// * @param type 接收到的数据类型 | ||
| 28 | -// * @param response 返回数据 | ||
| 29 | -// */ | ||
| 30 | -// void onXdyAsyncMessageReceiver(String type,String response); | ||
| 31 | -// } | ||
| 32 | -// private static OnXdyAsyncMessageLitener mOnXdyAsyncMessageLitener; | ||
| 33 | -// | ||
| 34 | -// /** | ||
| 35 | -// * 设置监听 | ||
| 36 | -// */ | ||
| 37 | -// public void setOnXdyAsyncMessageLitener(OnXdyAsyncMessageLitener onXdyAsyncMessageLitener){ | ||
| 38 | -// mOnXdyAsyncMessageLitener=onXdyAsyncMessageLitener; | ||
| 39 | -// } | ||
| 40 | -// private XdyInterface(){} | ||
| 41 | -// /** | ||
| 42 | -// * 初始化 | ||
| 43 | -// * @param context | ||
| 44 | -// */ | ||
| 45 | -// public static void init(Context context){ | ||
| 46 | -// if(context==null){ | ||
| 47 | -// throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL); | ||
| 48 | -// } | ||
| 49 | -// mXdyCore = XdyCore.getInstance(context); | ||
| 50 | -// mXdyCore.setXdyAsyncMessageListener(new XdyCore.OnXdyAsyncMessageListener() { | ||
| 51 | -// @Override | ||
| 52 | -// public void getSdyAsyncMessageListener(String id, String parameter) { | ||
| 53 | -// XdyLogUtil.e(null,""+"xdy init success"); | ||
| 54 | -// if(mOnXdyAsyncMessageLitener!=null){ | ||
| 55 | -// mOnXdyAsyncMessageLitener.onXdyAsyncMessageReceiver(id,parameter); | ||
| 56 | -// } | ||
| 57 | -// } | ||
| 58 | -// }); | ||
| 59 | -// } | ||
| 60 | -// | ||
| 61 | -// /** | ||
| 62 | -// * 接收用户传递进来的参数 | ||
| 63 | -// */ | ||
| 64 | -// public static void setAsyncApi(String type,String argument){ | ||
| 65 | -// judgeCore(); | ||
| 66 | -// mXdyCore.native2js(type,argument); | ||
| 67 | -// } | ||
| 68 | -// /*判断是否被初始化*/ | ||
| 69 | -// public static void judgeCore(){ | ||
| 70 | -// if(mXdyCore==null){ | ||
| 71 | -// throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT); | ||
| 72 | -// } | ||
| 73 | -// | ||
| 74 | -// } | ||
| 75 | -// public static XdyInterface getXdyInstance(){ | ||
| 76 | -// if(mXdyInterface==null){ | ||
| 77 | -// synchronized (XdyInterface.class){ | ||
| 78 | -// mXdyInterface=new XdyInterface(); | ||
| 79 | -// } | ||
| 80 | -// } | ||
| 81 | -// return mXdyInterface; | ||
| 82 | -// } | ||
| 83 | -//} |
| 1 | package com.mang.xdy.cache; | 1 | package com.mang.xdy.cache; |
| 2 | -/** | ||
| 3 | - * Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com). | ||
| 4 | - * | ||
| 5 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | - * you may not use this file except in compliance with the License. | ||
| 7 | - * You may obtain a copy of the License at | ||
| 8 | - * | ||
| 9 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | - * | ||
| 11 | - * Unless required by applicable law or agreed to in writing, software | ||
| 12 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | - * See the License for the specific language governing permissions and | ||
| 15 | - * limitations under the License. | ||
| 16 | - */ | ||
| 17 | 2 | ||
| 18 | import android.content.Context; | 3 | import android.content.Context; |
| 19 | import android.graphics.Bitmap; | 4 | import android.graphics.Bitmap; |
| @@ -196,7 +196,7 @@ public interface Constants { | @@ -196,7 +196,7 @@ public interface Constants { | ||
| 196 | /** | 196 | /** |
| 197 | * 断线重连时间间隔 | 197 | * 断线重连时间间隔 |
| 198 | */ | 198 | */ |
| 199 | - long TIME_NET_ERROR_RECONNECTION=6000; | 199 | + long TIME_NET_ERROR_RECONNECTION=5000; |
| 200 | 200 | ||
| 201 | /**********************************以下实现为自定义code 先定义后实现*********************************************************************/ | 201 | /**********************************以下实现为自定义code 先定义后实现*********************************************************************/ |
| 202 | /** | 202 | /** |
| @@ -157,6 +157,7 @@ public class XdyPlayerCore { | @@ -157,6 +157,7 @@ public class XdyPlayerCore { | ||
| 157 | libPlayer.SmartPlayerClose(playerHandle); | 157 | libPlayer.SmartPlayerClose(playerHandle); |
| 158 | playerHandle = 0; | 158 | playerHandle = 0; |
| 159 | } | 159 | } |
| 160 | + isPlaying = false; | ||
| 160 | } | 161 | } |
| 161 | /** | 162 | /** |
| 162 | * 停止播放,重置正在播放标识 | 163 | * 停止播放,重置正在播放标识 |
| 1 | -package com.mang.xdy.core; | ||
| 2 | - | ||
| 3 | -import android.app.Activity; | ||
| 4 | -import android.content.Context; | ||
| 5 | -import android.os.Handler; | ||
| 6 | -import android.os.Message; | ||
| 7 | -import android.text.TextUtils; | ||
| 8 | -import android.util.Log; | ||
| 9 | -import android.view.SurfaceView; | ||
| 10 | - | ||
| 11 | -import com.eventhandle.SmartEventCallback; | ||
| 12 | -import com.google.gson.Gson; | ||
| 13 | -import com.mang.xdy.bean.AudioPlayBean; | ||
| 14 | -import com.mang.xdy.bean.ErrorCodeEntity; | ||
| 15 | -import com.mang.xdy.bean.GetPublishPathReceiveBean; | ||
| 16 | -import com.mang.xdy.bean.PublisherSuccessEntity; | ||
| 17 | -import com.mang.xdy.bean.PublisherVideoReturnBean; | ||
| 18 | -import com.mang.xdy.bean.VideoPlayBean; | ||
| 19 | -import com.mang.xdy.cache.ACache; | ||
| 20 | -import com.mang.xdy.common.Constants; | ||
| 21 | -import com.mang.xdy.listener.ObserverListener; | ||
| 22 | -import com.mang.xdy.listener.SubjectListener; | ||
| 23 | -import com.mang.xdy.message.MsgManage; | ||
| 24 | -import com.mang.xdy.utils.JsonUtil; | ||
| 25 | -import com.mang.xdy.utils.NetWorkUtils; | ||
| 26 | -import com.mang.xdy.utils.PlayerUtils; | ||
| 27 | -import com.mang.xdy.utils.XdyLogUtil; | ||
| 28 | -import com.mang.xdy.utils.XdyStringUtils; | ||
| 29 | - | ||
| 30 | -import org.json.JSONException; | ||
| 31 | -import org.json.JSONObject; | ||
| 32 | - | ||
| 33 | -import java.util.ArrayList; | ||
| 34 | -import java.util.List; | ||
| 35 | - | ||
| 36 | -import static com.mang.xdy.utils.PlayerUtils.getPublishPathAudio; | ||
| 37 | -import static com.mang.xdy.utils.PlayerUtils.getPublishPathVideo; | ||
| 38 | - | ||
| 39 | -/** | ||
| 40 | - * 对外调用的接口 | ||
| 41 | - * Created by abao on 2017/3/31. | ||
| 42 | - * 受原先的文档设计的规则,所有方法的都是静态的方法,影响性能 | ||
| 43 | - * 考虑跟换文档,提升性能 | ||
| 44 | - */ | ||
| 45 | -public class XdySdk implements SubjectListener{ | ||
| 46 | - /** | ||
| 47 | - * 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件 | ||
| 48 | - */ | ||
| 49 | - private static XdyJsCore mXdyJsCore; | ||
| 50 | - private static XdySdk mXdySdk; | ||
| 51 | - private static Context mContext; | ||
| 52 | - private XdyPlayerCore mXdyPlayerCore; | ||
| 53 | - private XdyPublisherCore mXdyPublisherCore; | ||
| 54 | - /*消息管理*/ | ||
| 55 | - private static MsgManage mMsgManage; | ||
| 56 | - | ||
| 57 | - public static String TAG="xdysdk"; | ||
| 58 | - private String currentPlayId=""; | ||
| 59 | - /*缓存管理*/ | ||
| 60 | - private static ACache aCache; | ||
| 61 | - //TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏) | ||
| 62 | - private SurfaceView mSurfaceView_Publish; | ||
| 63 | - private Activity mActivity; | ||
| 64 | - /*是否正在推流,mcu自动断开的时候使用,推流成功后才表示正在使用*/ | ||
| 65 | - private boolean isPublisher =false; | ||
| 66 | -// /*Audio 推送中,resume需要使用*/ | ||
| 67 | - private boolean isPublisherAudio=false; | ||
| 68 | - /*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/ | ||
| 69 | - private boolean isReconnection=false; | ||
| 70 | - /*是否进行录制回放*/ | ||
| 71 | - private boolean isRecordPlayBack=false; | ||
| 72 | - /*观察者集合*/ | ||
| 73 | - private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>(); | ||
| 74 | - /*推流地址*/ | ||
| 75 | - private String publish_url=""; | ||
| 76 | - | ||
| 77 | - @Override | ||
| 78 | - public void add(ObserverListener observerListener) { | ||
| 79 | - observerListenerList.add(observerListener); | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - @Override | ||
| 83 | - public void notifyObserver(String type, String parameter) { | ||
| 84 | - handleData(type,parameter); | ||
| 85 | - XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter); | ||
| 86 | - | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - @Override | ||
| 90 | - public void remove(ObserverListener observerListener) { | ||
| 91 | - if(observerListenerList!=null){ | ||
| 92 | - if(observerListenerList.contains(observerListener)) { | ||
| 93 | - observerListenerList.remove(observerListener); | ||
| 94 | - } | ||
| 95 | - } | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - | ||
| 99 | - | ||
| 100 | - /** | ||
| 101 | - * 对外提供的异步消息接收接口) | ||
| 102 | - */ | ||
| 103 | - public interface OnXdyAsyncMessageLitener{ | ||
| 104 | - /** | ||
| 105 | - * | ||
| 106 | - * @param type 接收到的数据类型 | ||
| 107 | - * @param response 返回数据 | ||
| 108 | - */ | ||
| 109 | - void onXdyAsyncMessageReceiver(String type, String response); | ||
| 110 | - } | ||
| 111 | - private OnXdyAsyncMessageLitener mOnXdyAsyncMessageLitener; | ||
| 112 | - | ||
| 113 | - /** | ||
| 114 | - * 设置监听 | ||
| 115 | - */ | ||
| 116 | - public void setOnXdyAsyncMessageLitener(OnXdyAsyncMessageLitener onXdyAsyncMessageLitener){ | ||
| 117 | - judgeCore(); | ||
| 118 | - mOnXdyAsyncMessageLitener=onXdyAsyncMessageLitener; | ||
| 119 | - } | ||
| 120 | - private XdySdk(){} | ||
| 121 | - | ||
| 122 | - private static Handler handler=new Handler(){ | ||
| 123 | - @Override | ||
| 124 | - public void handleMessage(Message msg) { | ||
| 125 | - super.handleMessage(msg); | ||
| 126 | - if(msg.what==Constants.LEAVE_CLASS_CODE){ | ||
| 127 | - if(!NetWorkUtils.isNetworkConnected(mContext)) { | ||
| 128 | - if (mXdySdk != null) { | ||
| 129 | - mXdySdk.onPublisherStop(); | ||
| 130 | - handler.removeCallbacksAndMessages(null); | ||
| 131 | - } | ||
| 132 | - } | ||
| 133 | - } | ||
| 134 | - } | ||
| 135 | - }; | ||
| 136 | - /** | ||
| 137 | - * 初始化 | ||
| 138 | - * @param context | ||
| 139 | - */ | ||
| 140 | - public static void init(final Context context){ | ||
| 141 | - if(context==null){ | ||
| 142 | - throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL); | ||
| 143 | - } | ||
| 144 | - aCache=ACache.get(context); | ||
| 145 | - mContext=context; | ||
| 146 | - mXdyJsCore = XdyJsCore.getInstance(context); | ||
| 147 | - mMsgManage=MsgManage.getErrorMsgInstance(); | ||
| 148 | - } | ||
| 149 | - | ||
| 150 | - /** | ||
| 151 | - * 接收用户传递进来的参数(两个String 的参数都在这里处理) | ||
| 152 | - * @param type 类型 | ||
| 153 | - * @param argument 参数 | ||
| 154 | - */ | ||
| 155 | - public void api(final String type, final String argument){ | ||
| 156 | - judgeCore(); | ||
| 157 | - //再次停止播放器 | ||
| 158 | - switch (type){ | ||
| 159 | - case "stopPublishAudio": | ||
| 160 | - //停止推送音频 | ||
| 161 | - case "stopPublishVideo": | ||
| 162 | - //停止推流video(关闭视频:根据api) | ||
| 163 | - onPublisherStop(); | ||
| 164 | - break; | ||
| 165 | - case "stopAudio": | ||
| 166 | - //停止播放audio() | ||
| 167 | - case"stopVideo": | ||
| 168 | - //停止播放video( 停止播放:根据api) | ||
| 169 | - onPlayDestroy(); | ||
| 170 | - break; | ||
| 171 | - } | ||
| 172 | - handler.post(new Runnable() { | ||
| 173 | - @Override | ||
| 174 | - public void run() { | ||
| 175 | - mXdyJsCore.native2js(type, argument); | ||
| 176 | - } | ||
| 177 | - }); | ||
| 178 | - | ||
| 179 | - } | ||
| 180 | - | ||
| 181 | - /** | ||
| 182 | - * | ||
| 183 | - * @param type | ||
| 184 | - * @param | ||
| 185 | - * @param surfaceView | ||
| 186 | - * @param activity | ||
| 187 | - * @param | ||
| 188 | - * | ||
| 189 | - */ | ||
| 190 | - public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) { | ||
| 191 | - judgeString(type); | ||
| 192 | - switch (type) { | ||
| 193 | - case Constants.PLAY_AUDIO: | ||
| 194 | - //播放音频 | ||
| 195 | - /** | ||
| 196 | - * 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误 | ||
| 197 | - * | ||
| 198 | - */ | ||
| 199 | - String json_audio= aCache.getAsString(mediaId); | ||
| 200 | - if(TextUtils.isEmpty(json_audio)){ | ||
| 201 | - //TODO/给出相应的提示表示没有 这个id | ||
| 202 | - XdyLogUtil.e(TAG,"Play Audio Can not find this AudioId"); | ||
| 203 | - return; | ||
| 204 | - } | ||
| 205 | - currentPlayId=mediaId; | ||
| 206 | - AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class); | ||
| 207 | - if(audioPlayBean!=null) { | ||
| 208 | - String play_url_audio=""; | ||
| 209 | - if(isRecordPlayBack){ | ||
| 210 | - play_url_audio=audioPlayBean.getReplay(); | ||
| 211 | - }else{ | ||
| 212 | - play_url_audio=audioPlayBean.getRtmpUrl() ; | ||
| 213 | - if(mXdyPlayerCore==null) { | ||
| 214 | - mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_audio, activity); | ||
| 215 | - }else{ | ||
| 216 | - mXdyPlayerCore.onStopPlay(); | ||
| 217 | - } | ||
| 218 | - mXdyPlayerCore.playAudio(play_url_audio, new EventHande_Play()); | ||
| 219 | - } | ||
| 220 | - | ||
| 221 | - }else{ | ||
| 222 | - XdyLogUtil.e(TAG,"Can not get play Audio response"); | ||
| 223 | - } | ||
| 224 | - break; | ||
| 225 | - case Constants.PLAY_VIDEO: | ||
| 226 | - //播放视频 | ||
| 227 | - /** | ||
| 228 | - * 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误 | ||
| 229 | - * | ||
| 230 | - */ | ||
| 231 | - String json_video= aCache.getAsString(mediaId); | ||
| 232 | - if(TextUtils.isEmpty(json_video)){ | ||
| 233 | - ///给出相应的提示表示没有 这个id | ||
| 234 | - XdyLogUtil.e(TAG,"Play Video Can not find this VideoId"); | ||
| 235 | - return; | ||
| 236 | - } | ||
| 237 | - currentPlayId=mediaId; | ||
| 238 | - VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class); | ||
| 239 | - if(videoPlayBean!=null){ | ||
| 240 | - String play_url_video=""; | ||
| 241 | - if(isRecordPlayBack){ | ||
| 242 | - play_url_video=videoPlayBean.getReplay(); | ||
| 243 | - }else{ | ||
| 244 | - play_url_video=videoPlayBean.getRtmpUrl(); | ||
| 245 | - if(mXdyPlayerCore==null) { | ||
| 246 | - mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_video, activity); | ||
| 247 | - }else{ | ||
| 248 | - //重复播放时候 | ||
| 249 | - mXdyPlayerCore.onStopPlay(); | ||
| 250 | - } | ||
| 251 | - mXdyPlayerCore.playVideo(play_url_video, surfaceView,new EventHande_Play()); | ||
| 252 | - } | ||
| 253 | - | ||
| 254 | - }else{ | ||
| 255 | - //统一提示推流错误 | ||
| 256 | - XdyLogUtil.e(TAG,"Can not get play Video response"); | ||
| 257 | - } | ||
| 258 | - break; | ||
| 259 | - case Constants.PUBLISH_VIDEO: | ||
| 260 | - //打开推流视频 | ||
| 261 | - /** | ||
| 262 | - * 用户发起这个推流的请求的时候, | ||
| 263 | - * 1,去获取推流地址 | ||
| 264 | - * 2,判断地址时候有用,有用的话打开播放器,开启推流的过程 | ||
| 265 | - * 3,推流成功告知后台,和用户 | ||
| 266 | - * | ||
| 267 | - */ | ||
| 268 | - getPublishPathVideo(); | ||
| 269 | - mSurfaceView_Publish=surfaceView; | ||
| 270 | - mActivity=activity; | ||
| 271 | - break; | ||
| 272 | - case Constants.PUBLISH_AUDIO: | ||
| 273 | - //只推送音频 | ||
| 274 | - getPublishPathAudio(); | ||
| 275 | -// mSurfaceView=surfaceView; | ||
| 276 | - mActivity=activity; | ||
| 277 | - break; | ||
| 278 | - | ||
| 279 | - } | ||
| 280 | - } | ||
| 281 | - /*判断是否被初始化*/ | ||
| 282 | - private void judgeCore(){ | ||
| 283 | - if(mXdyJsCore==null){ | ||
| 284 | - throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT); | ||
| 285 | - } | ||
| 286 | - } | ||
| 287 | - /*判断type是否为空*/ | ||
| 288 | - private void judgeString(String type){ | ||
| 289 | - if(TextUtils.isEmpty(type)){ | ||
| 290 | - XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL); | ||
| 291 | - } | ||
| 292 | - } | ||
| 293 | - /*判断是否是合法的url*/ | ||
| 294 | - protected void judgeUrl(String url){ | ||
| 295 | - if (url == null) | ||
| 296 | - return; | ||
| 297 | - | ||
| 298 | - // rtmp:// | ||
| 299 | - if (url.length() < 8) { | ||
| 300 | - Log.e(TAG, "Input publish url error:" + url); | ||
| 301 | - return; | ||
| 302 | - } | ||
| 303 | - | ||
| 304 | - if (!url.startsWith("rtmp://")) { | ||
| 305 | - Log.e(TAG, "Input publish url error:" + url); | ||
| 306 | - return; | ||
| 307 | - } | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | - public static XdySdk getXdyInstance(){ | ||
| 311 | - if(mXdySdk ==null){ | ||
| 312 | - synchronized (XdySdk.class){ | ||
| 313 | - mXdySdk =new XdySdk(); | ||
| 314 | - } | ||
| 315 | - } | ||
| 316 | - return mXdySdk; | ||
| 317 | - } | ||
| 318 | - /** | ||
| 319 | - *core获取到的数据处理 | ||
| 320 | - * @param type | ||
| 321 | - * @param response | ||
| 322 | - */ | ||
| 323 | - private void handleData(String type,String response){ | ||
| 324 | - //开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url | ||
| 325 | - /*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和 | ||
| 326 | - audio | ||
| 327 | - plublisher Video | ||
| 328 | - publisher Audio | ||
| 329 | - | ||
| 330 | - */ | ||
| 331 | - switch (type) { | ||
| 332 | - case Constants.CLASS_JOIN_SUCCESS: | ||
| 333 | - //判断是否是录制回放,调整播流地址 | ||
| 334 | - JSONObject jsonObject = null; | ||
| 335 | - try { | ||
| 336 | - jsonObject = new JSONObject(response); | ||
| 337 | - isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack"); | ||
| 338 | - } catch (JSONException e) { | ||
| 339 | - e.printStackTrace(); | ||
| 340 | - } | ||
| 341 | - handleListener(type,response); | ||
| 342 | - break; | ||
| 343 | - case Constants.VIDEO_GET_PUBLISH_PATH: | ||
| 344 | - //推流地址的返回值拿到正确的推流地址直接开始推流 | ||
| 345 | - //打开推流视频 | ||
| 346 | -// String publishPath=XdyStringUtils.stringToJson(response); | ||
| 347 | - String publishPath=response; | ||
| 348 | - GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class); | ||
| 349 | - | ||
| 350 | - if(getPublishPathReceiveBean!=null) { | ||
| 351 | - //可以推流了 | ||
| 352 | - if (getPublishPathReceiveBean.getCode() == 0) { | ||
| 353 | - //TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路 | ||
| 354 | - String video_url = getPublishPathReceiveBean.getPublishUrl(); | ||
| 355 | - aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url); | ||
| 356 | - //判断 | ||
| 357 | - if (mSurfaceView_Publish == null) { | ||
| 358 | - //todo 输出提示 | ||
| 359 | - throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW); | ||
| 360 | - } | ||
| 361 | - if (mActivity == null) { | ||
| 362 | - //TODo 给出提示 | ||
| 363 | - throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY); | ||
| 364 | - } | ||
| 365 | - if (mXdyPublisherCore == null) { | ||
| 366 | - mXdyPublisherCore = new XdyPublisherCore(1, 1, mActivity); | ||
| 367 | - } | ||
| 368 | - publish_url=video_url; | ||
| 369 | - isPublisher =true; | ||
| 370 | - isPublisherAudio=false; | ||
| 371 | - mXdyPublisherCore.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish()); | ||
| 372 | -// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 373 | - //// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断) | ||
| 374 | - setPublishSendSuccessVideo(video_url); | ||
| 375 | - }else{ | ||
| 376 | - mMsgManage.getPublishVideoPathError(); | ||
| 377 | - } | ||
| 378 | - }else{ | ||
| 379 | - //给出提示 | ||
| 380 | - mMsgManage.getPublishVideoPathError(); | ||
| 381 | - } | ||
| 382 | - break; | ||
| 383 | - case Constants.AUDIO_GET_PUBLISH_PATH: | ||
| 384 | - //推流地址的返回值拿到正确的推流地址直接开始推流 | ||
| 385 | - //打开推流视频 | ||
| 386 | - String audio_path=XdyStringUtils.stringToJson(response); | ||
| 387 | - GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(audio_path,GetPublishPathReceiveBean.class); | ||
| 388 | - if(getPublishPathReceiveBean_Audio!=null&&getPublishPathReceiveBean_Audio.getCode()==0){ | ||
| 389 | - //可以推流了 | ||
| 390 | - String audio_url=getPublishPathReceiveBean_Audio.getPublishUrl(); | ||
| 391 | - //TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字 | ||
| 392 | - aCache.put(Constants.GET_VIDEO_PUBLISH_PATH,audio_url); | ||
| 393 | - //判断 | ||
| 394 | -// if (mSurfaceView==null){ | ||
| 395 | -// //todo 输出提示 | ||
| 396 | -// XdyLogUtil.e(TAG,"surfaceView is null"); | ||
| 397 | -// return; | ||
| 398 | -// } | ||
| 399 | - if(mActivity==null){ | ||
| 400 | - //TODo 给出提示 | ||
| 401 | - XdyLogUtil.e(TAG,"activity is null"); | ||
| 402 | - return; | ||
| 403 | - } | ||
| 404 | - if(mXdyPublisherCore==null) | ||
| 405 | - mXdyPublisherCore=new XdyPublisherCore(1,0,mActivity); | ||
| 406 | - mXdyPublisherCore.publisherAudio(audio_url,new EventHande_Publish()); | ||
| 407 | - publish_url=audio_url; | ||
| 408 | - isPublisher =true; | ||
| 409 | - isPublisherAudio=true; | ||
| 410 | - //// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断) | ||
| 411 | - PlayerUtils.setPublishSendSuccessAudio(audio_url); | ||
| 412 | - }else{ | ||
| 413 | - //给出提示 | ||
| 414 | - mMsgManage.getPublishVideoPathError(); | ||
| 415 | - } | ||
| 416 | - break; | ||
| 417 | - case Constants.PUBLISH_AUDIO: | ||
| 418 | - //只推送音频 | ||
| 419 | - //接收后台是否接收到推流URl的地址 | ||
| 420 | - String publishReplay_Audio=response; | ||
| 421 | - XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay_Audio)); | ||
| 422 | - PublisherVideoReturnBean publisherVideoReturnBean_audio=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay_Audio),PublisherVideoReturnBean.class); | ||
| 423 | - if(publisherVideoReturnBean_audio!=null&&publisherVideoReturnBean_audio.getCode()==0){ | ||
| 424 | - XdyLogUtil.e(TAG,"后台成功接收到,推流的地址"); | ||
| 425 | - //TODO | ||
| 426 | - | ||
| 427 | - handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 428 | - }else{ | ||
| 429 | - //TODO | ||
| 430 | - handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 431 | - } | ||
| 432 | - break; | ||
| 433 | - case Constants.VIDEO_PUBLISH_RESULT: | ||
| 434 | - //接收发送推流地址给后台返回的信息 | ||
| 435 | - String publishReplay=response; | ||
| 436 | - XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay)); | ||
| 437 | - PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class); | ||
| 438 | - if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){ | ||
| 439 | - XdyLogUtil.e(TAG,"后台成功接收到,推流的地址"); | ||
| 440 | - //TODO | ||
| 441 | - | ||
| 442 | - handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 443 | - }else{ | ||
| 444 | - //TODO | ||
| 445 | - handleListener(Constants.ERROR_CODE,"{\n" + | ||
| 446 | - " \"code\": 804,\n" + | ||
| 447 | - " \"reson\": \"推流失败\"\n" + | ||
| 448 | - "}"); | ||
| 449 | - } | ||
| 450 | - break; | ||
| 451 | - case Constants.VIDEO_PLAY: | ||
| 452 | - //获取推流的地址,需要保存起来 | ||
| 453 | - //解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况 | ||
| 454 | - String video=response; | ||
| 455 | - VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class); | ||
| 456 | - if(videoPlayBean!=null) { | ||
| 457 | - if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) { | ||
| 458 | - aCache.put(videoPlayBean.getMediaId() + "", video); | ||
| 459 | - handleListener(type, videoPlayBean.getMediaId() + ""); | ||
| 460 | - } | ||
| 461 | - } | ||
| 462 | - break; | ||
| 463 | - case Constants.AUDIO_PLAY: | ||
| 464 | - String audio=response; | ||
| 465 | - AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class); | ||
| 466 | - if(audioPlayBean!=null){ | ||
| 467 | - if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) { | ||
| 468 | - aCache.put(audioPlayBean.getMediaId() + "", audio); | ||
| 469 | - handleListener(type, audioPlayBean.getMediaId() + ""); | ||
| 470 | - } | ||
| 471 | - } | ||
| 472 | - break; | ||
| 473 | - case Constants.ERROR_CODE: | ||
| 474 | - ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class); | ||
| 475 | - if(errorCodeEntity!=null){ | ||
| 476 | - if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){ | ||
| 477 | - /** | ||
| 478 | - * 方案 一 1,正在直播的时候mcu无故断开,需要重新连接 | ||
| 479 | - * 2,class exit 时候主动课堂停止,停止推流 | ||
| 480 | - * 利用mcu的生命周期,加入课堂成功后去请求数据 | ||
| 481 | - */ | ||
| 482 | - // 方案 二 mcu 断开,页面也断开,用户需要手动重新调用 | ||
| 483 | - if(isPublisher) { | ||
| 484 | - if(!NetWorkUtils.isNetworkConnected(mContext)){ | ||
| 485 | - //todo判断是否有网络,没有网络的话就让其退出 | ||
| 486 | - // TOdo 延迟10秒, | ||
| 487 | -// onPublisherStop(); | ||
| 488 | - handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION); | ||
| 489 | - } | ||
| 490 | - isReconnection=true; | ||
| 491 | - } | ||
| 492 | - } | ||
| 493 | - } | ||
| 494 | - handleListener(type,response); | ||
| 495 | - break; | ||
| 496 | - case Constants.CLASS_EXIT: | ||
| 497 | - /** | ||
| 498 | - * 处理正在推流视频,课堂退出的情况,(用户操作退出界面) | ||
| 499 | - * 此时,停止推流,清除surfaceview Activtity 数据,url数据 | ||
| 500 | - */ | ||
| 501 | - if(isPublisher){ | ||
| 502 | - onPublisherStop(); | ||
| 503 | - } | ||
| 504 | - handleListener(type,response); | ||
| 505 | - break; | ||
| 506 | - default:{ | ||
| 507 | - handleListener(type,response); | ||
| 508 | - } | ||
| 509 | - | ||
| 510 | - } | ||
| 511 | - | ||
| 512 | - } | ||
| 513 | - | ||
| 514 | - /** | ||
| 515 | - * 处理所有向外发送的接口数据 | ||
| 516 | - * @param type | ||
| 517 | - * @param parameter | ||
| 518 | - */ | ||
| 519 | - private void handleListener(String type,String parameter){ | ||
| 520 | - if(mOnXdyAsyncMessageLitener!=null){ | ||
| 521 | - mOnXdyAsyncMessageLitener.onXdyAsyncMessageReceiver(type,parameter); | ||
| 522 | - } | ||
| 523 | - for(ObserverListener o:observerListenerList){ | ||
| 524 | - o.observerUpData(type,parameter); | ||
| 525 | - } | ||
| 526 | - } | ||
| 527 | - | ||
| 528 | - /** | ||
| 529 | - * 销毁播放音视频 | ||
| 530 | - * @param id | ||
| 531 | - * @return | ||
| 532 | - */ | ||
| 533 | - public boolean onPlayStop(String id){ | ||
| 534 | - if(currentPlayId.equals(id)) { | ||
| 535 | - if (mXdyPlayerCore != null) { | ||
| 536 | - mXdyPlayerCore.onStopPlay(); | ||
| 537 | -// mXdyPlayerCore = null; | ||
| 538 | - | ||
| 539 | - } | ||
| 540 | - return true; | ||
| 541 | - } | ||
| 542 | - return false; | ||
| 543 | - } | ||
| 544 | - /** | ||
| 545 | - * 退出时清除信息(重置js监听) | ||
| 546 | - */ | ||
| 547 | - public void removeAll(){ | ||
| 548 | - if(mXdyPlayerCore!=null) { | ||
| 549 | - mXdyPlayerCore.onPause(); | ||
| 550 | - } | ||
| 551 | - if(mXdyJsCore!=null&&!isRecordPlayBack) { | ||
| 552 | - mXdyJsCore.init(mContext); | ||
| 553 | - } | ||
| 554 | - } | ||
| 555 | - | ||
| 556 | - /** | ||
| 557 | - * 结束时调用 | ||
| 558 | - */ | ||
| 559 | - public void onPlayDestroy(){ | ||
| 560 | - if (mXdyPlayerCore != null) { | ||
| 561 | - mXdyPlayerCore.onStopPlay(); | ||
| 562 | - mXdyPlayerCore = null; | ||
| 563 | - } | ||
| 564 | - | ||
| 565 | - | ||
| 566 | - } | ||
| 567 | - | ||
| 568 | - /** | ||
| 569 | - * 推送视频音频停止方法(最后调用的方法) | ||
| 570 | - * @deprecated daniu sdk handle best | ||
| 571 | - */ | ||
| 572 | - public void onPublisherStop(){ | ||
| 573 | - if(mXdyPublisherCore!=null){ | ||
| 574 | - mXdyPublisherCore.onStopPublisher(); | ||
| 575 | - mXdyPublisherCore=null; | ||
| 576 | - } | ||
| 577 | - //如果正在推流,msurfaceView ,mActivity不清空 | ||
| 578 | - if(!isPublisher) { | ||
| 579 | - if (mSurfaceView_Publish != null) { | ||
| 580 | - mSurfaceView_Publish = null; | ||
| 581 | - } | ||
| 582 | - if (mActivity != null) { | ||
| 583 | - mActivity = null; | ||
| 584 | - } | ||
| 585 | - } | ||
| 586 | - isPublisher =false; | ||
| 587 | - isReconnection=false; | ||
| 588 | - isPublisherAudio=false; | ||
| 589 | - } | ||
| 590 | - | ||
| 591 | - /** | ||
| 592 | - * onPause 方法时走的周期 | ||
| 593 | - */ | ||
| 594 | - public void onPublisherPause(){ | ||
| 595 | - if(mXdyPublisherCore!=null){ | ||
| 596 | - mXdyPublisherCore.onPausePublisher(); | ||
| 597 | - } | ||
| 598 | - } | ||
| 599 | - | ||
| 600 | - /** | ||
| 601 | - * onResume 调用,目前是空方法 | ||
| 602 | - * TODO 只有一个boolean | ||
| 603 | - * 开始isPublish 为false | ||
| 604 | - * 开始推流初始化后onresume 就是开始 | ||
| 605 | - * @deprecated 大牛 sdk处理的更好 | ||
| 606 | - */ | ||
| 607 | - public void onPublisherResume(){ | ||
| 608 | - if(!isPublisher){ | ||
| 609 | - return; | ||
| 610 | - } | ||
| 611 | - if(mXdyPublisherCore!=null) { | ||
| 612 | - mXdyPublisherCore.onResumePublisher(); | ||
| 613 | - if (!TextUtils.isEmpty(publish_url)) { | ||
| 614 | - if(!isPublisherAudio){ | ||
| 615 | - mXdyPublisherCore.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish()); | ||
| 616 | - }else{ | ||
| 617 | - mXdyPublisherCore.publisherAudio(publish_url,new EventHande_Publish()); | ||
| 618 | - } | ||
| 619 | - | ||
| 620 | - } | ||
| 621 | - } | ||
| 622 | - } | ||
| 623 | - class EventHande_Play implements SmartEventCallback { | ||
| 624 | - @Override | ||
| 625 | - public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) { | ||
| 626 | - switch (code) { | ||
| 627 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED: | ||
| 628 | - Log.e(TAG, "开始。。"); | ||
| 629 | - break; | ||
| 630 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING: | ||
| 631 | - Log.e(TAG, "连接中。。"); | ||
| 632 | - break; | ||
| 633 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED: | ||
| 634 | - Log.e(TAG, "连接失败。。"); | ||
| 635 | - break; | ||
| 636 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED: | ||
| 637 | - Log.e(TAG, "连接成功。。"); | ||
| 638 | - //TODO //如果连接成功发送连接成功信息,判断的方式有待考虑 | ||
| 639 | -// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 640 | -// XdySdk.getXdyInstance().notifyObserver("video_success",""); | ||
| 641 | - break; | ||
| 642 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED: | ||
| 643 | - Log.e(TAG, "连接断开。。"); | ||
| 644 | - break; | ||
| 645 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP: | ||
| 646 | - Log.i(TAG, "关闭。。"); | ||
| 647 | - notifyObserver("play_stop",currentPlayId+""); | ||
| 648 | - break; | ||
| 649 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO: | ||
| 650 | - Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2); | ||
| 651 | - //在这里最接近得到播放的成功的准确回调 | ||
| 652 | - notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+""); | ||
| 653 | - break; | ||
| 654 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED: | ||
| 655 | - Log.e(TAG, "收不到媒体数据,可能是url错误。。"); | ||
| 656 | - } | ||
| 657 | - | ||
| 658 | - } | ||
| 659 | - } | ||
| 660 | - | ||
| 661 | - | ||
| 662 | - class EventHande_Publish implements SmartEventCallback { | ||
| 663 | - @Override | ||
| 664 | - public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) { | ||
| 665 | - switch (code) { | ||
| 666 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED: | ||
| 667 | - Log.e(TAG, "开始。。"); | ||
| 668 | - break; | ||
| 669 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING: | ||
| 670 | - Log.e(TAG, "连接中。。"); | ||
| 671 | - break; | ||
| 672 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED: | ||
| 673 | - Log.e(TAG, "连接失败。。"); | ||
| 674 | - break; | ||
| 675 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED: | ||
| 676 | - Log.e(TAG, "连接成功。。"); | ||
| 677 | - //TODO //如果连接成功发送连接成功信息,判断的方式有待考虑 | ||
| 678 | -// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 679 | -// XdySdk.getXdyInstance().notifyObserver("video_success",""); | ||
| 680 | - break; | ||
| 681 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED: | ||
| 682 | - Log.e(TAG, "连接断开。。"); | ||
| 683 | - break; | ||
| 684 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP: | ||
| 685 | - Log.i(TAG, "关闭。。"); | ||
| 686 | - notifyObserver("play_stop",currentPlayId+""); | ||
| 687 | - break; | ||
| 688 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO: | ||
| 689 | - Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2); | ||
| 690 | - //在这里最接近得到播放的成功的准确回调 | ||
| 691 | - notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+""); | ||
| 692 | - break; | ||
| 693 | - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED: | ||
| 694 | - Log.e(TAG, "收不到媒体数据,可能是url错误。。"); | ||
| 695 | - } | ||
| 696 | - | ||
| 697 | - } | ||
| 698 | - } | ||
| 699 | - /** | ||
| 700 | - * 向后台发送推流数据(Auido)成功信息 | ||
| 701 | - * @param url | ||
| 702 | - */ | ||
| 703 | - protected static void setPublishSendSuccessAudio(String url) { | ||
| 704 | - PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity(); | ||
| 705 | - if (!TextUtils.isEmpty(url)) { | ||
| 706 | - publisherEntity.setPublishUrl(url); | ||
| 707 | - final String pamp = new Gson().toJson(publisherEntity); | ||
| 708 | - XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp); | ||
| 709 | - | ||
| 710 | - } | ||
| 711 | - } | ||
| 712 | - | ||
| 713 | - /** | ||
| 714 | - * 向后台发送推流(Video)成功的信息 | ||
| 715 | - * @param url | ||
| 716 | - */ | ||
| 717 | - protected static void setPublishSendSuccessVideo(String url) { | ||
| 718 | - PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity(); | ||
| 719 | - if (!TextUtils.isEmpty(url)) { | ||
| 720 | - publisherEntity.setPublishUrl(url); | ||
| 721 | - final String pamp = new Gson().toJson(publisherEntity); | ||
| 722 | - XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+""); | ||
| 723 | - XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp); | ||
| 724 | - | ||
| 725 | - } | ||
| 726 | - } | ||
| 727 | -} | 1 | +package com.mang.xdy.core; |
| 2 | + | ||
| 3 | +import android.app.Activity; | ||
| 4 | +import android.content.Context; | ||
| 5 | +import android.os.Handler; | ||
| 6 | +import android.os.Message; | ||
| 7 | +import android.text.TextUtils; | ||
| 8 | +import android.util.Log; | ||
| 9 | +import android.view.SurfaceView; | ||
| 10 | + | ||
| 11 | +import com.eventhandle.SmartEventCallback; | ||
| 12 | +import com.google.gson.Gson; | ||
| 13 | +import com.mang.xdy.bean.AudioPlayBean; | ||
| 14 | +import com.mang.xdy.bean.ErrorCodeEntity; | ||
| 15 | +import com.mang.xdy.bean.GetPublishPathReceiveBean; | ||
| 16 | +import com.mang.xdy.bean.PublisherSuccessEntity; | ||
| 17 | +import com.mang.xdy.bean.PublisherVideoReturnBean; | ||
| 18 | +import com.mang.xdy.bean.VideoPlayBean; | ||
| 19 | +import com.mang.xdy.cache.ACache; | ||
| 20 | +import com.mang.xdy.common.Constants; | ||
| 21 | +import com.mang.xdy.listener.ObserverListener; | ||
| 22 | +import com.mang.xdy.listener.SubjectListener; | ||
| 23 | +import com.mang.xdy.message.MsgManage; | ||
| 24 | +import com.mang.xdy.utils.JsonUtil; | ||
| 25 | +import com.mang.xdy.utils.NetWorkUtils; | ||
| 26 | +import com.mang.xdy.utils.PlayerUtils; | ||
| 27 | +import com.mang.xdy.utils.XdyLogUtil; | ||
| 28 | +import com.mang.xdy.utils.XdyStringUtils; | ||
| 29 | + | ||
| 30 | +import org.json.JSONException; | ||
| 31 | +import org.json.JSONObject; | ||
| 32 | + | ||
| 33 | +import java.util.ArrayList; | ||
| 34 | +import java.util.List; | ||
| 35 | + | ||
| 36 | +import static com.mang.xdy.utils.PlayerUtils.getPublishPathAudio; | ||
| 37 | +import static com.mang.xdy.utils.PlayerUtils.getPublishPathVideo; | ||
| 38 | + | ||
| 39 | +/** | ||
| 40 | + * 对外调用的接口 | ||
| 41 | + * Created by abao on 2017/3/31. | ||
| 42 | + * 受原先的文档设计的规则,所有方法的都是静态的方法,影响性能 | ||
| 43 | + * 考虑跟换文档,提升性能 | ||
| 44 | + */ | ||
| 45 | +public class XdySdk implements SubjectListener{ | ||
| 46 | + /** | ||
| 47 | + * 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件 | ||
| 48 | + */ | ||
| 49 | + private static XdyJsCore mXdyJsCore; | ||
| 50 | + private static XdySdk mXdySdk; | ||
| 51 | + private static Context mContext; | ||
| 52 | + private XdyPlayerCore mXdyPlayerCore; | ||
| 53 | + private XdyPublisherCore mXdyPublisherCore; | ||
| 54 | + /*消息管理*/ | ||
| 55 | + private static MsgManage mMsgManage; | ||
| 56 | + | ||
| 57 | + public static String TAG="xdysdk"; | ||
| 58 | + /*当前播放视频的id*/ | ||
| 59 | + private String currentPlayId=""; | ||
| 60 | + /*缓存管理*/ | ||
| 61 | + private static ACache aCache; | ||
| 62 | + //TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏) | ||
| 63 | + private SurfaceView mSurfaceView_Publish; | ||
| 64 | + private Activity mActivity; | ||
| 65 | + /*是否正在推流,mcu自动断开的时候使用,推流成功后才表示正在使用*/ | ||
| 66 | + private boolean isPublisher =false; | ||
| 67 | +// /*Audio 推送中,resume需要使用*/ | ||
| 68 | + private boolean isPublisherAudio=false; | ||
| 69 | + /*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/ | ||
| 70 | + private boolean isReconnection=false; | ||
| 71 | + /*是否进行录制回放*/ | ||
| 72 | + private boolean isRecordPlayBack=false; | ||
| 73 | + /*观察者集合*/ | ||
| 74 | + private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>(); | ||
| 75 | + /*推流地址*/ | ||
| 76 | + private String publish_url=""; | ||
| 77 | + /*保存nodeid ,自己的唯一标识*/ | ||
| 78 | + private int nodeId=0; | ||
| 79 | + | ||
| 80 | + @Override | ||
| 81 | + public void add(ObserverListener observerListener) { | ||
| 82 | + observerListenerList.add(observerListener); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public void notifyObserver(String type, String parameter) { | ||
| 87 | + handleData(type,parameter); | ||
| 88 | + XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter); | ||
| 89 | + | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + @Override | ||
| 93 | + public void remove(ObserverListener observerListener) { | ||
| 94 | + if(observerListenerList!=null){ | ||
| 95 | + if(observerListenerList.contains(observerListener)) { | ||
| 96 | + observerListenerList.remove(observerListener); | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + private XdySdk(){} | ||
| 101 | + | ||
| 102 | + private static Handler handler=new Handler(){ | ||
| 103 | + @Override | ||
| 104 | + public void handleMessage(Message msg) { | ||
| 105 | + super.handleMessage(msg); | ||
| 106 | + if(msg.what==Constants.LEAVE_CLASS_CODE){ | ||
| 107 | + if(!NetWorkUtils.isNetworkConnected(mContext)) { | ||
| 108 | + if (mXdySdk != null) { | ||
| 109 | + mXdySdk.onPublisherStop(); | ||
| 110 | + handler.removeCallbacksAndMessages(null); | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | + }; | ||
| 116 | + /** | ||
| 117 | + * 初始化 | ||
| 118 | + * @param context | ||
| 119 | + */ | ||
| 120 | + public static void init(final Context context){ | ||
| 121 | + if(context==null){ | ||
| 122 | + throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL); | ||
| 123 | + } | ||
| 124 | + aCache=ACache.get(context); | ||
| 125 | + mContext=context; | ||
| 126 | + mXdyJsCore = XdyJsCore.getInstance(context); | ||
| 127 | + mMsgManage=MsgManage.getErrorMsgInstance(); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + /** | ||
| 131 | + * 接收用户传递进来的参数(两个String 的参数都在这里处理) | ||
| 132 | + * @param type 类型 | ||
| 133 | + * @param argument 参数 | ||
| 134 | + */ | ||
| 135 | + public void api(final String type, final String argument){ | ||
| 136 | + judgeCore(); | ||
| 137 | + //再次停止播放器 | ||
| 138 | + switch (type){ | ||
| 139 | + case "stopPublishAudio": | ||
| 140 | + //停止推送音频 | ||
| 141 | + case "stopPublishVideo": | ||
| 142 | + //停止推流video(关闭视频:根据api) | ||
| 143 | + onPublisherStop(); | ||
| 144 | + break; | ||
| 145 | + case "stopAudio": | ||
| 146 | + //停止播放audio() | ||
| 147 | + case"stopVideo": | ||
| 148 | + //停止播放video( 停止播放:根据api) | ||
| 149 | + onPlayDestroy(); | ||
| 150 | + break; | ||
| 151 | + } | ||
| 152 | + handler.post(new Runnable() { | ||
| 153 | + @Override | ||
| 154 | + public void run() { | ||
| 155 | + mXdyJsCore.native2js(type, argument); | ||
| 156 | + } | ||
| 157 | + }); | ||
| 158 | + | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * | ||
| 163 | + * @param type | ||
| 164 | + * @param | ||
| 165 | + * @param surfaceView | ||
| 166 | + * @param activity | ||
| 167 | + * @param | ||
| 168 | + * | ||
| 169 | + */ | ||
| 170 | + public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) { | ||
| 171 | + judgeString(type); | ||
| 172 | + switch (type) { | ||
| 173 | + case Constants.PLAY_AUDIO: | ||
| 174 | + //判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误 | ||
| 175 | + String json_audio= aCache.getAsString(mediaId); | ||
| 176 | + if(TextUtils.isEmpty(json_audio)){ | ||
| 177 | + //TODO/给出相应的提示表示没有 这个id | ||
| 178 | + XdyLogUtil.e(TAG,"Play Audio Can not find this mediaId"); | ||
| 179 | + return; | ||
| 180 | + } | ||
| 181 | + currentPlayId=mediaId; | ||
| 182 | + AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class); | ||
| 183 | + if(audioPlayBean!=null) { | ||
| 184 | + String play_url_audio=""; | ||
| 185 | + if(isRecordPlayBack){ | ||
| 186 | + //如果是回放给出。m3u8的id用户 用户需要自己获取play_url_audio=audioPlayBean.getReplay(); | ||
| 187 | + }else{ | ||
| 188 | + play_url_audio=audioPlayBean.getRtmpUrl() ; | ||
| 189 | + if(mXdyPlayerCore==null) { | ||
| 190 | + mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_audio, activity); | ||
| 191 | + }else{ | ||
| 192 | + mXdyPlayerCore.onStopPlay(); | ||
| 193 | + } | ||
| 194 | + mXdyPlayerCore.playAudio(play_url_audio, new EventHande_Play()); | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + }else{ | ||
| 198 | + XdyLogUtil.e(TAG,"Can not get play Audio response"); | ||
| 199 | + } | ||
| 200 | + break; | ||
| 201 | + case Constants.PLAY_VIDEO: | ||
| 202 | + //播放视频 | ||
| 203 | + // 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误 | ||
| 204 | + String json_video= aCache.getAsString(mediaId); | ||
| 205 | + if(TextUtils.isEmpty(json_video)){ | ||
| 206 | + ///给出相应的提示表示没有 这个id | ||
| 207 | + XdyLogUtil.e(TAG,"Play Video Can not find this mediaId"); | ||
| 208 | + return; | ||
| 209 | + } | ||
| 210 | + currentPlayId=mediaId; | ||
| 211 | + VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class); | ||
| 212 | + if(videoPlayBean!=null){ | ||
| 213 | + String play_url_video=""; | ||
| 214 | + if(isRecordPlayBack){ | ||
| 215 | +// play_url_video=videoPlayBean.getReplay(); | ||
| 216 | + }else{ | ||
| 217 | + play_url_video=videoPlayBean.getRtmpUrl(); | ||
| 218 | + if(mXdyPlayerCore==null) { | ||
| 219 | + mXdyPlayerCore = XdyPlayerCore.getXdyPlayerCore(play_url_video, activity); | ||
| 220 | + }else{ | ||
| 221 | + //重复播放时候 | ||
| 222 | + mXdyPlayerCore.onStopPlay(); | ||
| 223 | + } | ||
| 224 | + mXdyPlayerCore.playVideo(play_url_video, surfaceView,new EventHande_Play()); | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + }else{ | ||
| 228 | + //统一提示推流错误 | ||
| 229 | + XdyLogUtil.e(TAG,"Can not get play Video response"); | ||
| 230 | + } | ||
| 231 | + break; | ||
| 232 | + case Constants.PUBLISH_VIDEO: | ||
| 233 | + /** | ||
| 234 | + * 用户发起这个推流的请求的时候, | ||
| 235 | + * 1,去获取推流地址 | ||
| 236 | + * 2,判断地址时候有用,有用的话打开播放器,开启推流的过程 | ||
| 237 | + * 3,推流成功告知后台,和用户 | ||
| 238 | + */ | ||
| 239 | + getPublishPathVideo(); | ||
| 240 | + mSurfaceView_Publish=surfaceView; | ||
| 241 | + mActivity=activity; | ||
| 242 | + break; | ||
| 243 | + case Constants.PUBLISH_AUDIO: | ||
| 244 | + //只推送音频 | ||
| 245 | + getPublishPathAudio(); | ||
| 246 | +// mSurfaceView=surfaceView; | ||
| 247 | + mActivity=activity; | ||
| 248 | + break; | ||
| 249 | + | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + /*判断是否被初始化*/ | ||
| 253 | + private void judgeCore(){ | ||
| 254 | + if(mXdyJsCore==null){ | ||
| 255 | + throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT); | ||
| 256 | + } | ||
| 257 | + } | ||
| 258 | + /*判断type是否为空*/ | ||
| 259 | + private void judgeString(String type){ | ||
| 260 | + if(TextUtils.isEmpty(type)){ | ||
| 261 | + XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL); | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | + /*判断是否是合法的url*/ | ||
| 265 | + protected void judgeUrl(String url){ | ||
| 266 | + if (url == null) | ||
| 267 | + return; | ||
| 268 | + | ||
| 269 | + // rtmp:// | ||
| 270 | + if (url.length() < 8) { | ||
| 271 | + Log.e(TAG, "Input publish url error:" + url); | ||
| 272 | + return; | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + if (!url.startsWith("rtmp://")) { | ||
| 276 | + Log.e(TAG, "Input publish url error:" + url); | ||
| 277 | + return; | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + public static XdySdk getXdyInstance(){ | ||
| 282 | + if(mXdySdk ==null){ | ||
| 283 | + synchronized (XdySdk.class){ | ||
| 284 | + mXdySdk =new XdySdk(); | ||
| 285 | + } | ||
| 286 | + } | ||
| 287 | + return mXdySdk; | ||
| 288 | + } | ||
| 289 | + /** | ||
| 290 | + *core获取到的数据处理 | ||
| 291 | + * @param type | ||
| 292 | + * @param response | ||
| 293 | + */ | ||
| 294 | + private void handleData(String type,String response){ | ||
| 295 | + //开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url | ||
| 296 | + /*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和 | ||
| 297 | + audio | ||
| 298 | + plublisher Video | ||
| 299 | + publisher Audio | ||
| 300 | + | ||
| 301 | + */ | ||
| 302 | + switch (type) { | ||
| 303 | + case Constants.CLASS_JOIN_SUCCESS: | ||
| 304 | + //判断是否是录制回放,调整播流地址 | ||
| 305 | + JSONObject jsonObject = null; | ||
| 306 | + try { | ||
| 307 | + jsonObject = new JSONObject(response); | ||
| 308 | + isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack"); | ||
| 309 | + nodeId=jsonObject.optInt("nodeId"); | ||
| 310 | + } catch (JSONException e) { | ||
| 311 | + e.printStackTrace(); | ||
| 312 | + } | ||
| 313 | + handleListener(type,response); | ||
| 314 | + break; | ||
| 315 | + case Constants.VIDEO_GET_PUBLISH_PATH: | ||
| 316 | + //推流地址的返回值拿到正确的推流地址直接开始推流 | ||
| 317 | + //打开推流视频 | ||
| 318 | +// String publishPath=XdyStringUtils.stringToJson(response); | ||
| 319 | + String publishPath=response; | ||
| 320 | + GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class); | ||
| 321 | + if(getPublishPathReceiveBean!=null) { | ||
| 322 | + //可以推流了 | ||
| 323 | + if (getPublishPathReceiveBean.getCode() == 0) { | ||
| 324 | + //TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路 | ||
| 325 | + String video_url = getPublishPathReceiveBean.getPublishUrl(); | ||
| 326 | + aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url); | ||
| 327 | + //判断 | ||
| 328 | + if (mSurfaceView_Publish == null) { | ||
| 329 | + //todo 输出提示 | ||
| 330 | + throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW); | ||
| 331 | + } | ||
| 332 | + if (mActivity == null) { | ||
| 333 | + //TODo 给出提示 | ||
| 334 | + throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY); | ||
| 335 | + } | ||
| 336 | + if (mXdyPublisherCore == null) { | ||
| 337 | + mXdyPublisherCore = new XdyPublisherCore(1, 1, mActivity); | ||
| 338 | + }else{ | ||
| 339 | + //todo 如果不为空的话是已经播放过,得清理上次的 | ||
| 340 | + mXdyPlayerCore.onPause(); | ||
| 341 | + } | ||
| 342 | + publish_url=video_url; | ||
| 343 | + isPublisher =true; | ||
| 344 | + isPublisherAudio=false; | ||
| 345 | + mXdyPublisherCore.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish()); | ||
| 346 | +// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 347 | + //// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断) | ||
| 348 | + setPublishSendSuccessVideo(video_url); | ||
| 349 | + }else{ | ||
| 350 | + mMsgManage.getPublishVideoPathError(); | ||
| 351 | + } | ||
| 352 | + }else{ | ||
| 353 | + //给出提示 | ||
| 354 | + //TODO | ||
| 355 | + handleListener(Constants.ERROR_CODE,"{\n" + | ||
| 356 | + " \"code\": 804,\n" + | ||
| 357 | + " \"reson\": \"推流失败\"\n" + | ||
| 358 | + "}"); | ||
| 359 | + } | ||
| 360 | + break; | ||
| 361 | + case Constants.AUDIO_GET_PUBLISH_PATH: | ||
| 362 | + //推流地址的返回值拿到正确的推流地址直接开始推流 | ||
| 363 | + //打开推流视频 | ||
| 364 | + String audio_path=XdyStringUtils.stringToJson(response); | ||
| 365 | + GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(audio_path,GetPublishPathReceiveBean.class); | ||
| 366 | + if(getPublishPathReceiveBean_Audio!=null&&getPublishPathReceiveBean_Audio.getCode()==0){ | ||
| 367 | + //可以推流了 | ||
| 368 | + String audio_url=getPublishPathReceiveBean_Audio.getPublishUrl(); | ||
| 369 | + //TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字 | ||
| 370 | + aCache.put(Constants.GET_VIDEO_PUBLISH_PATH,audio_url); | ||
| 371 | + //判断 | ||
| 372 | +// if (mSurfaceView==null){ | ||
| 373 | +// //todo 输出提示 | ||
| 374 | +// XdyLogUtil.e(TAG,"surfaceView is null"); | ||
| 375 | +// return; | ||
| 376 | +// } | ||
| 377 | + if(mActivity==null){ | ||
| 378 | + //TODo 给出提示 | ||
| 379 | + XdyLogUtil.e(TAG,"activity is null"); | ||
| 380 | + return; | ||
| 381 | + } | ||
| 382 | + if(mXdyPublisherCore==null) { | ||
| 383 | + mXdyPublisherCore = new XdyPublisherCore(1, 0, mActivity); | ||
| 384 | + }else { | ||
| 385 | + //todo 如果不为空的话是已经播放过,得清理上次的 | ||
| 386 | + mXdyPlayerCore.onPause(); | ||
| 387 | + } | ||
| 388 | + mXdyPublisherCore.publisherAudio(audio_url,new EventHande_Publish()); | ||
| 389 | + publish_url=audio_url; | ||
| 390 | + isPublisher =true; | ||
| 391 | + isPublisherAudio=true; | ||
| 392 | + //// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断) | ||
| 393 | + PlayerUtils.setPublishSendSuccessAudio(audio_url); | ||
| 394 | + }else{ | ||
| 395 | + //给出提示 | ||
| 396 | + //TODO | ||
| 397 | + handleListener(Constants.ERROR_CODE,"{\n" + | ||
| 398 | + " \"code\": 804,\n" + | ||
| 399 | + " \"reson\": \"推流失败\"\n" + | ||
| 400 | + "}"); | ||
| 401 | + } | ||
| 402 | + break; | ||
| 403 | + case Constants.PUBLISH_AUDIO: | ||
| 404 | + //只推送音频 | ||
| 405 | + //接收后台是否接收到推流URl的地址 | ||
| 406 | + String publishReplay_Audio=response; | ||
| 407 | + XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay_Audio)); | ||
| 408 | + PublisherVideoReturnBean publisherVideoReturnBean_audio=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay_Audio),PublisherVideoReturnBean.class); | ||
| 409 | + if(publisherVideoReturnBean_audio!=null&&publisherVideoReturnBean_audio.getCode()==0){ | ||
| 410 | + XdyLogUtil.e(TAG,"后台成功接收到,推流的地址"); | ||
| 411 | + //TODO | ||
| 412 | + | ||
| 413 | + handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 414 | + }else{ | ||
| 415 | + //TODO | ||
| 416 | + handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 417 | + } | ||
| 418 | + break; | ||
| 419 | + case Constants.VIDEO_PUBLISH_RESULT: | ||
| 420 | + //接收发送推流地址给后台返回的信息 | ||
| 421 | + String publishReplay=response; | ||
| 422 | + XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay)); | ||
| 423 | + PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class); | ||
| 424 | + if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){ | ||
| 425 | + XdyLogUtil.e(TAG,"后台成功接收到,推流的地址"); | ||
| 426 | + //TODO | ||
| 427 | + | ||
| 428 | + handleListener(Constants.PUBLISH_RERUEN_SUCCESS,""); | ||
| 429 | + }else{ | ||
| 430 | + //TODO | ||
| 431 | + handleListener(Constants.ERROR_CODE,"{\n" + | ||
| 432 | + " \"code\": 804,\n" + | ||
| 433 | + " \"reson\": \"推流失败\"\n" + | ||
| 434 | + "}"); | ||
| 435 | + } | ||
| 436 | + break; | ||
| 437 | + case Constants.VIDEO_PLAY: | ||
| 438 | + //获取推流的地址,需要保存起来 | ||
| 439 | + //解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况 | ||
| 440 | + String video=response; | ||
| 441 | + VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class); | ||
| 442 | + if(videoPlayBean!=null) { | ||
| 443 | +// if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) { | ||
| 444 | + if(nodeId!=videoPlayBean.getFromNodeId()) { | ||
| 445 | + //过滤自己推送的video | ||
| 446 | + aCache.put(videoPlayBean.getMediaId() + "", video); | ||
| 447 | + handleListener(type, videoPlayBean.getMediaId() + ""); | ||
| 448 | + } | ||
| 449 | + }else{ | ||
| 450 | + XdyLogUtil.e(TAG,"video play json error"); | ||
| 451 | + } | ||
| 452 | + break; | ||
| 453 | + case Constants.AUDIO_PLAY: | ||
| 454 | + String audio=response; | ||
| 455 | + AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class); | ||
| 456 | + if(audioPlayBean!=null){ | ||
| 457 | +// if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) { | ||
| 458 | + if(nodeId!=audioPlayBean.getFromNodeId()) { | ||
| 459 | + aCache.put(audioPlayBean.getMediaId() + "", audio); | ||
| 460 | + handleListener(type, audioPlayBean.getMediaId() + ""); | ||
| 461 | + } | ||
| 462 | + } | ||
| 463 | + break; | ||
| 464 | + case Constants.ERROR_CODE: | ||
| 465 | + ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class); | ||
| 466 | + if(errorCodeEntity!=null){ | ||
| 467 | + if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){ | ||
| 468 | + /** | ||
| 469 | + * 方案 一 1,正在直播的时候mcu无故断开,需要重新连接 | ||
| 470 | + * 2,class exit 时候主动课堂停止,停止推流 | ||
| 471 | + * 利用mcu的生命周期,加入课堂成功后去请求数据 | ||
| 472 | + */ | ||
| 473 | + // 方案 二 mcu 断开,页面也断开,用户需要手动重新调用 | ||
| 474 | + if(isPublisher) { | ||
| 475 | + if(!NetWorkUtils.isNetworkConnected(mContext)){ | ||
| 476 | + //todo判断是否有网络,没有网络的话就让其退出 | ||
| 477 | + // TOdo 延迟5秒, | ||
| 478 | +// onPublisherStop(); | ||
| 479 | + handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION); | ||
| 480 | + } | ||
| 481 | + isReconnection=true; | ||
| 482 | + } | ||
| 483 | + } | ||
| 484 | + } | ||
| 485 | + handleListener(type,response); | ||
| 486 | + break; | ||
| 487 | + case Constants.CLASS_EXIT: | ||
| 488 | + /** | ||
| 489 | + * 处理正在推流视频,课堂退出的情况,(用户操作退出界面) | ||
| 490 | + * 此时,停止推流,清除surfaceview Activtity 数据,url数据 | ||
| 491 | + */ | ||
| 492 | + if(isPublisher){ | ||
| 493 | + onPublisherStop(); | ||
| 494 | + } | ||
| 495 | + handleListener(type,response); | ||
| 496 | + break; | ||
| 497 | + default:{ | ||
| 498 | + handleListener(type,response); | ||
| 499 | + } | ||
| 500 | + | ||
| 501 | + } | ||
| 502 | + | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + /** | ||
| 506 | + * 处理所有向外发送的接口数据 | ||
| 507 | + * @param type | ||
| 508 | + * @param parameter | ||
| 509 | + */ | ||
| 510 | + private void handleListener(String type,String parameter){ | ||
| 511 | + XdyLogUtil.e(TAG,"type:"+type+"parameter:"+parameter); | ||
| 512 | + for(ObserverListener o:observerListenerList){ | ||
| 513 | + o.observerUpData(type,parameter); | ||
| 514 | + } | ||
| 515 | + } | ||
| 516 | + | ||
| 517 | + /** | ||
| 518 | + * 销毁播放音视频 | ||
| 519 | + * @param id | ||
| 520 | + * @return | ||
| 521 | + */ | ||
| 522 | + public boolean onPlayStop(String id){ | ||
| 523 | + if(currentPlayId.equals(id)) { | ||
| 524 | + if (mXdyPlayerCore != null) { | ||
| 525 | + mXdyPlayerCore.onStopPlay(); | ||
| 526 | +// mXdyPlayerCore = null; | ||
| 527 | + | ||
| 528 | + } | ||
| 529 | + return true; | ||
| 530 | + } | ||
| 531 | + return false; | ||
| 532 | + } | ||
| 533 | + /** | ||
| 534 | + * 退出时清除信息(重置js监听) | ||
| 535 | + */ | ||
| 536 | + public void removeAll(){ | ||
| 537 | + if(mXdyPlayerCore!=null) { | ||
| 538 | + mXdyPlayerCore.onPause(); | ||
| 539 | + } | ||
| 540 | + if(mXdyJsCore!=null&&!isRecordPlayBack) { | ||
| 541 | + mXdyJsCore.init(mContext); | ||
| 542 | + } | ||
| 543 | + onPublisherStop(); | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + /** | ||
| 547 | + * 结束时调用 | ||
| 548 | + */ | ||
| 549 | + public void onPlayDestroy(){ | ||
| 550 | + if (mXdyPlayerCore != null) { | ||
| 551 | + mXdyPlayerCore.onStopPlay(); | ||
| 552 | + mXdyPlayerCore = null; | ||
| 553 | + } | ||
| 554 | + | ||
| 555 | + | ||
| 556 | + } | ||
| 557 | + | ||
| 558 | + /** | ||
| 559 | + * 推送视频音频停止方法(最后调用的方法) | ||
| 560 | + * @deprecated daniu sdk handle best | ||
| 561 | + */ | ||
| 562 | + public void onPublisherStop(){ | ||
| 563 | + if(mXdyPublisherCore!=null){ | ||
| 564 | + mXdyPublisherCore.onStopPublisher(); | ||
| 565 | + mXdyPublisherCore=null; | ||
| 566 | + } | ||
| 567 | + //如果正在推流,msurfaceView ,mActivity不清空 | ||
| 568 | + if(!isPublisher) { | ||
| 569 | + if (mSurfaceView_Publish != null) { | ||
| 570 | + mSurfaceView_Publish = null; | ||
| 571 | + } | ||
| 572 | + if (mActivity != null) { | ||
| 573 | + mActivity = null; | ||
| 574 | + } | ||
| 575 | + } | ||
| 576 | + isPublisher =false; | ||
| 577 | + isReconnection=false; | ||
| 578 | + isPublisherAudio=false; | ||
| 579 | + } | ||
| 580 | + | ||
| 581 | + /** | ||
| 582 | + * onPause 方法时走的周期 | ||
| 583 | + */ | ||
| 584 | + public void onPublisherPause(){ | ||
| 585 | + if(mXdyPublisherCore!=null){ | ||
| 586 | + mXdyPublisherCore.onPausePublisher(); | ||
| 587 | + } | ||
| 588 | + } | ||
| 589 | + | ||
| 590 | + /** | ||
| 591 | + * | ||
| 592 | + * TODO 只有一个boolean | ||
| 593 | + * 开始isPublish 为false | ||
| 594 | + * 开始推流初始化后onresume 就是开始 | ||
| 595 | + * @deprecated 大牛 sdk处理的更好 | ||
| 596 | + */ | ||
| 597 | + public void onPublisherResume(){ | ||
| 598 | + if(!isPublisher){ | ||
| 599 | + return; | ||
| 600 | + } | ||
| 601 | + if(mXdyPublisherCore!=null) { | ||
| 602 | + mXdyPublisherCore.onResumePublisher(); | ||
| 603 | + if (!TextUtils.isEmpty(publish_url)) { | ||
| 604 | + if(!isPublisherAudio){ | ||
| 605 | + mXdyPublisherCore.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish()); | ||
| 606 | + }else{ | ||
| 607 | + mXdyPublisherCore.publisherAudio(publish_url,new EventHande_Publish()); | ||
| 608 | + } | ||
| 609 | + | ||
| 610 | + } | ||
| 611 | + } | ||
| 612 | + } | ||
| 613 | + class EventHande_Play implements SmartEventCallback { | ||
| 614 | + @Override | ||
| 615 | + public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) { | ||
| 616 | + switch (code) { | ||
| 617 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED: | ||
| 618 | + Log.e(TAG, "开始。。"); | ||
| 619 | + break; | ||
| 620 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING: | ||
| 621 | + Log.e(TAG, "连接中。。"); | ||
| 622 | + break; | ||
| 623 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED: | ||
| 624 | + Log.e(TAG, "连接失败。。"); | ||
| 625 | + break; | ||
| 626 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED: | ||
| 627 | + Log.e(TAG, "连接成功。。"); | ||
| 628 | + //TODO //如果连接成功发送连接成功信息,判断的方式有待考虑 | ||
| 629 | +// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 630 | +// XdySdk.getXdyInstance().notifyObserver("video_success",""); | ||
| 631 | + break; | ||
| 632 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED: | ||
| 633 | + Log.e(TAG, "连接断开。。"); | ||
| 634 | + break; | ||
| 635 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP: | ||
| 636 | + Log.i(TAG, "关闭。。"); | ||
| 637 | + notifyObserver("play_stop",currentPlayId+""); | ||
| 638 | + break; | ||
| 639 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO: | ||
| 640 | + Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2); | ||
| 641 | + //在这里最接近得到播放的成功的准确回调 | ||
| 642 | + notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+""); | ||
| 643 | + break; | ||
| 644 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED: | ||
| 645 | + Log.e(TAG, "收不到媒体数据,可能是url错误。。"); | ||
| 646 | + } | ||
| 647 | + | ||
| 648 | + } | ||
| 649 | + } | ||
| 650 | + | ||
| 651 | + | ||
| 652 | + class EventHande_Publish implements SmartEventCallback { | ||
| 653 | + @Override | ||
| 654 | + public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) { | ||
| 655 | + switch (code) { | ||
| 656 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED: | ||
| 657 | + Log.e(TAG, "开始。。"); | ||
| 658 | + break; | ||
| 659 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING: | ||
| 660 | + Log.e(TAG, "连接中。。"); | ||
| 661 | + break; | ||
| 662 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED: | ||
| 663 | + Log.e(TAG, "连接失败。。"); | ||
| 664 | + break; | ||
| 665 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED: | ||
| 666 | + Log.e(TAG, "连接成功。。"); | ||
| 667 | + //TODO //如果连接成功发送连接成功信息,判断的方式有待考虑 | ||
| 668 | +// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH)); | ||
| 669 | +// XdySdk.getXdyInstance().notifyObserver("video_success",""); | ||
| 670 | + break; | ||
| 671 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED: | ||
| 672 | + Log.e(TAG, "连接断开。。"); | ||
| 673 | + break; | ||
| 674 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP: | ||
| 675 | + Log.i(TAG, "关闭。。"); | ||
| 676 | + notifyObserver("play_stop",currentPlayId+""); | ||
| 677 | + break; | ||
| 678 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO: | ||
| 679 | + Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2); | ||
| 680 | + //在这里最接近得到播放的成功的准确回调 | ||
| 681 | + notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+""); | ||
| 682 | + break; | ||
| 683 | + case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED: | ||
| 684 | + Log.e(TAG, "收不到媒体数据,可能是url错误。。"); | ||
| 685 | + } | ||
| 686 | + | ||
| 687 | + } | ||
| 688 | + } | ||
| 689 | + /** | ||
| 690 | + * 向后台发送推流数据(Auido)成功信息 | ||
| 691 | + * @param url | ||
| 692 | + */ | ||
| 693 | + protected static void setPublishSendSuccessAudio(String url) { | ||
| 694 | + PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity(); | ||
| 695 | + if (!TextUtils.isEmpty(url)) { | ||
| 696 | + publisherEntity.setPublishUrl(url); | ||
| 697 | + final String pamp = new Gson().toJson(publisherEntity); | ||
| 698 | + XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp); | ||
| 699 | + | ||
| 700 | + } | ||
| 701 | + } | ||
| 702 | + | ||
| 703 | + /** | ||
| 704 | + * 向后台发送推流(Video)成功的信息 | ||
| 705 | + * @param url | ||
| 706 | + */ | ||
| 707 | + protected static void setPublishSendSuccessVideo(String url) { | ||
| 708 | + PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity(); | ||
| 709 | + if (!TextUtils.isEmpty(url)) { | ||
| 710 | + publisherEntity.setPublishUrl(url); | ||
| 711 | + final String pamp = new Gson().toJson(publisherEntity); | ||
| 712 | + XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+""); | ||
| 713 | + XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp); | ||
| 714 | + | ||
| 715 | + } | ||
| 716 | + } | ||
| 717 | +} |
| 1 | -package com.mang.xdy.utils; | ||
| 2 | - | ||
| 3 | -import android.text.TextUtils; | ||
| 4 | -import android.util.Log; | ||
| 5 | - | ||
| 6 | -import com.google.gson.Gson; | ||
| 7 | -import com.google.gson.reflect.TypeToken; | ||
| 8 | - | ||
| 9 | -import org.json.JSONException; | ||
| 10 | -import org.json.JSONObject; | ||
| 11 | - | ||
| 12 | -import java.lang.reflect.Type; | ||
| 13 | -import java.util.HashMap; | ||
| 14 | -import java.util.List; | ||
| 15 | -import java.util.Map; | ||
| 16 | - | ||
| 17 | -/** | ||
| 18 | - * 封装的是使用Gson解析json的方法 | ||
| 19 | - * | ||
| 20 | - * @author Administrator | ||
| 21 | - */ | ||
| 22 | -public class JsonUtil { | ||
| 23 | - | ||
| 24 | - private static final String TAG = JsonUtil.class.getSimpleName(); | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * 把一个map变成json字符串 | ||
| 28 | - * | ||
| 29 | - * @param map | ||
| 30 | - * @return | ||
| 31 | - */ | ||
| 32 | - public static String parseMapToJson(Map<?, ?> map) { | ||
| 33 | - try { | ||
| 34 | - Gson gson = new Gson(); | ||
| 35 | - return gson.toJson(map); | ||
| 36 | - } catch (Exception e) { | ||
| 37 | - } | ||
| 38 | - return null; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public static String parseListToJson(List<?> list) { | ||
| 42 | - try { | ||
| 43 | - Gson gson = new Gson(); | ||
| 44 | - return gson.toJson(list); | ||
| 45 | - } catch (Exception e) { | ||
| 46 | - } | ||
| 47 | - return null; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - /** | ||
| 51 | - * 把一个json字符串变成对象 | ||
| 52 | - * | ||
| 53 | - * @param json | ||
| 54 | - * @param cls | ||
| 55 | - * @return | ||
| 56 | - */ | ||
| 57 | - public static <T> T parseJsonToBean(String json, Class<T> cls) { | ||
| 58 | - Gson gson = new Gson(); | ||
| 59 | - T t = null; | ||
| 60 | - try { | ||
| 61 | - t = gson.fromJson(json, cls); | ||
| 62 | - } catch (Exception e) { | ||
| 63 | - Log.e(TAG,e.getMessage()); | ||
| 64 | - e.printStackTrace(); | ||
| 65 | - } | ||
| 66 | - return t; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - /** | ||
| 70 | - * 把json字符串变成map | ||
| 71 | - * | ||
| 72 | - * @param json | ||
| 73 | - * @return | ||
| 74 | - */ | ||
| 75 | - public static HashMap<String, Object> parseJsonToMap(String json) { | ||
| 76 | - Gson gson = new Gson(); | ||
| 77 | - Type type = new TypeToken<HashMap<String, Object>>() { | ||
| 78 | - }.getType(); | ||
| 79 | - HashMap<String, Object> map = null; | ||
| 80 | - try { | ||
| 81 | - map = gson.fromJson(json, type); | ||
| 82 | - } catch (Exception e) { | ||
| 83 | - } | ||
| 84 | - return map; | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - /** | ||
| 88 | - * 把json字符串变成集合 | ||
| 89 | - * params: new TypeToken<List<yourbean>>(){}.getType(), | ||
| 90 | - * | ||
| 91 | - * @param json | ||
| 92 | - * @param type new TypeToken<List<yourbean>>(){}.getType() | ||
| 93 | - * @return | ||
| 94 | - */ | ||
| 95 | - public static List<?> parseJsonToList(String json, Type type) { | ||
| 96 | - Gson gson = new Gson(); | ||
| 97 | - List<?> list = gson.fromJson(json, type); | ||
| 98 | - return list; | ||
| 99 | - } | ||
| 100 | - | ||
| 101 | - /** | ||
| 102 | - * 获取json串中某个字段的值,注意,只能获取同一层级的value | ||
| 103 | - * | ||
| 104 | - * @param json | ||
| 105 | - * @param key | ||
| 106 | - * @return | ||
| 107 | - */ | ||
| 108 | - public static String getFieldValue(String json, String key) { | ||
| 109 | - if (TextUtils.isEmpty(json)) | ||
| 110 | - return null; | ||
| 111 | - if (!json.contains(key)) | ||
| 112 | - return ""; | ||
| 113 | - JSONObject jsonObject = null; | ||
| 114 | - String value = null; | ||
| 115 | - try { | ||
| 116 | - jsonObject = new JSONObject(json); | ||
| 117 | - value = jsonObject.getString(key); | ||
| 118 | - } catch (JSONException e) { | ||
| 119 | - e.printStackTrace(); | ||
| 120 | - } | ||
| 121 | - return value; | ||
| 122 | - } | ||
| 123 | - | ||
| 124 | -} | 1 | +package com.mang.xdy.utils; |
| 2 | + | ||
| 3 | +import android.text.TextUtils; | ||
| 4 | +import android.util.Log; | ||
| 5 | + | ||
| 6 | +import com.google.gson.Gson; | ||
| 7 | +import com.google.gson.reflect.TypeToken; | ||
| 8 | + | ||
| 9 | +import org.json.JSONException; | ||
| 10 | +import org.json.JSONObject; | ||
| 11 | + | ||
| 12 | +import java.lang.reflect.Type; | ||
| 13 | +import java.util.HashMap; | ||
| 14 | +import java.util.List; | ||
| 15 | +import java.util.Map; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 封装的是使用Gson解析json的方法 | ||
| 19 | + * | ||
| 20 | + * @author abao | ||
| 21 | + */ | ||
| 22 | +public class JsonUtil { | ||
| 23 | + | ||
| 24 | + private static final String TAG = JsonUtil.class.getSimpleName(); | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 把一个map变成json字符串 | ||
| 28 | + * | ||
| 29 | + * @param map | ||
| 30 | + * @return | ||
| 31 | + */ | ||
| 32 | + public static String parseMapToJson(Map<?, ?> map) { | ||
| 33 | + try { | ||
| 34 | + Gson gson = new Gson(); | ||
| 35 | + return gson.toJson(map); | ||
| 36 | + } catch (Exception e) { | ||
| 37 | + } | ||
| 38 | + return null; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public static String parseListToJson(List<?> list) { | ||
| 42 | + try { | ||
| 43 | + Gson gson = new Gson(); | ||
| 44 | + return gson.toJson(list); | ||
| 45 | + } catch (Exception e) { | ||
| 46 | + } | ||
| 47 | + return null; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 把一个json字符串变成对象 | ||
| 52 | + * | ||
| 53 | + * @param json | ||
| 54 | + * @param cls | ||
| 55 | + * @return | ||
| 56 | + */ | ||
| 57 | + public static <T> T parseJsonToBean(String json, Class<T> cls) { | ||
| 58 | + Gson gson = new Gson(); | ||
| 59 | + T t = null; | ||
| 60 | + try { | ||
| 61 | + t = gson.fromJson(json, cls); | ||
| 62 | + } catch (Exception e) { | ||
| 63 | + Log.e(TAG,e.getMessage()); | ||
| 64 | + e.printStackTrace(); | ||
| 65 | + } | ||
| 66 | + return t; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + /** | ||
| 70 | + * 把json字符串变成map | ||
| 71 | + * | ||
| 72 | + * @param json | ||
| 73 | + * @return | ||
| 74 | + */ | ||
| 75 | + public static HashMap<String, Object> parseJsonToMap(String json) { | ||
| 76 | + Gson gson = new Gson(); | ||
| 77 | + Type type = new TypeToken<HashMap<String, Object>>() { | ||
| 78 | + }.getType(); | ||
| 79 | + HashMap<String, Object> map = null; | ||
| 80 | + try { | ||
| 81 | + map = gson.fromJson(json, type); | ||
| 82 | + } catch (Exception e) { | ||
| 83 | + } | ||
| 84 | + return map; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * 把json字符串变成集合 | ||
| 89 | + * params: new TypeToken<List<yourbean>>(){}.getType(), | ||
| 90 | + * | ||
| 91 | + * @param json | ||
| 92 | + * @param type new TypeToken<List<yourbean>>(){}.getType() | ||
| 93 | + * @return | ||
| 94 | + */ | ||
| 95 | + public static List<?> parseJsonToList(String json, Type type) { | ||
| 96 | + Gson gson = new Gson(); | ||
| 97 | + List<?> list = gson.fromJson(json, type); | ||
| 98 | + return list; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * 获取json串中某个字段的值,注意,只能获取同一层级的value | ||
| 103 | + * | ||
| 104 | + * @param json | ||
| 105 | + * @param key | ||
| 106 | + * @return | ||
| 107 | + */ | ||
| 108 | + public static String getFieldValue(String json, String key) { | ||
| 109 | + if (TextUtils.isEmpty(json)) | ||
| 110 | + return null; | ||
| 111 | + if (!json.contains(key)) | ||
| 112 | + return ""; | ||
| 113 | + JSONObject jsonObject = null; | ||
| 114 | + String value = null; | ||
| 115 | + try { | ||
| 116 | + jsonObject = new JSONObject(json); | ||
| 117 | + value = jsonObject.getString(key); | ||
| 118 | + } catch (JSONException e) { | ||
| 119 | + e.printStackTrace(); | ||
| 120 | + } | ||
| 121 | + return value; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | +} |
| 1 | -package com.mang.xdy.utils; | ||
| 2 | - | ||
| 3 | -import android.text.TextUtils; | ||
| 4 | -import android.util.Log; | ||
| 5 | - | ||
| 6 | -import java.util.Locale; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Created by abao on 2017/3/30. | ||
| 10 | - */ | ||
| 11 | - | ||
| 12 | -public class XdyStringUtils { | ||
| 13 | - private static String TAG="xdysdk"; | ||
| 14 | - public static String stringToJson(String s,boolean isJSjson){ | ||
| 15 | - StringBuffer sb = new StringBuffer(); | ||
| 16 | - for(int i=0; i<s.length(); i++){ | ||
| 17 | - char c =s.charAt(i); | ||
| 18 | - switch(c){ | ||
| 19 | - case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break; | ||
| 20 | - case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break; | ||
| 21 | - case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码 | ||
| 22 | - case'/': sb.append("\\/");break; | ||
| 23 | - case'\b':sb.append("\\b");break;//退格 | ||
| 24 | - case'\f':sb.append("\\f");break;//走纸换页 | ||
| 25 | - case'\n':sb.append("\\n");break;//换行 | ||
| 26 | - case'\r':sb.append("\\r");break;//回车 | ||
| 27 | - case'\t':sb.append("\\t");break;//横向跳格 | ||
| 28 | - default: sb.append(c); | ||
| 29 | - }} | ||
| 30 | - return sb.toString(); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public static String stringToJson(String s){ | ||
| 34 | -// StringBuffer sb = new StringBuffer(); | ||
| 35 | -// for(int i=0; i<s.length(); i++){ | ||
| 36 | -// char c =s.charAt(i); | ||
| 37 | -// switch(c){ | ||
| 38 | -//// case'\"': sb.append(""); break; | ||
| 39 | -// case'\'': sb.append(""); break; | ||
| 40 | -// default: sb.append(c); | ||
| 41 | -// }} | ||
| 42 | - String resString=""; | ||
| 43 | - if(!TextUtils.isEmpty(s)&&s.length()>2) { | ||
| 44 | - String temp = s.replace("\\", ""); | ||
| 45 | - resString = temp.substring(1, temp.length() - 1); | ||
| 46 | - } | ||
| 47 | - return resString; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - public static void judgeUrl(String url){ | ||
| 51 | - if (url == null) | ||
| 52 | - return; | ||
| 53 | - | ||
| 54 | - // rtmp:// | ||
| 55 | - if (url.length() < 8) { | ||
| 56 | - Log.e(TAG, "Input publish url error:" + url); | ||
| 57 | - return; | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - if (!url.startsWith("rtmp://")) { | ||
| 61 | - Log.e(TAG, "Input publish url error:" + url); | ||
| 62 | - return; | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - | ||
| 66 | - /** | ||
| 67 | - * 时间 | ||
| 68 | - * @param currentTime | ||
| 69 | - * @return | ||
| 70 | - */ | ||
| 71 | - private String generateTime(long currentTime) { | ||
| 72 | - int totalSeconds = (int) (currentTime); | ||
| 73 | - | ||
| 74 | - int seconds = totalSeconds % 60; | ||
| 75 | - int minutes = (totalSeconds / 60) % 60; | ||
| 76 | - int hours = totalSeconds / 3600; | ||
| 77 | - | ||
| 78 | - if (hours > 0) { | ||
| 79 | - return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, | ||
| 80 | - seconds).toString(); | ||
| 81 | - } else { | ||
| 82 | - return String.format(Locale.US, "%02d:%02d", minutes, seconds) | ||
| 83 | - .toString(); | ||
| 84 | - } | ||
| 85 | - } | ||
| 86 | -} | 1 | +package com.mang.xdy.utils; |
| 2 | + | ||
| 3 | +import android.text.TextUtils; | ||
| 4 | +import android.util.Log; | ||
| 5 | + | ||
| 6 | +import java.util.Locale; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Created by abao on 2017/3/30. | ||
| 10 | + */ | ||
| 11 | + | ||
| 12 | +public class XdyStringUtils { | ||
| 13 | + private static String TAG="xdysdk"; | ||
| 14 | + public static String stringToJson(String s,boolean isJSjson){ | ||
| 15 | + StringBuffer sb = new StringBuffer(); | ||
| 16 | + for(int i=0; i<s.length(); i++){ | ||
| 17 | + char c =s.charAt(i); | ||
| 18 | + switch(c){ | ||
| 19 | + case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break; | ||
| 20 | + case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break; | ||
| 21 | + case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码 | ||
| 22 | + case'/': sb.append("\\/");break; | ||
| 23 | + case'\b':sb.append("\\b");break;//退格 | ||
| 24 | + case'\f':sb.append("\\f");break;//走纸换页 | ||
| 25 | + case'\n':sb.append("\\n");break;//换行 | ||
| 26 | + case'\r':sb.append("\\r");break;//回车 | ||
| 27 | + case'\t':sb.append("\\t");break;//横向跳格 | ||
| 28 | + default: sb.append(c); | ||
| 29 | + }} | ||
| 30 | + return sb.toString(); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public static String stringToJson(String s){ | ||
| 34 | + String resString=""; | ||
| 35 | + if(!TextUtils.isEmpty(s)&&s.length()>2) { | ||
| 36 | + String temp = s.replace("\\", ""); | ||
| 37 | + resString = temp.substring(1, temp.length() - 1); | ||
| 38 | + } | ||
| 39 | + return resString; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public static void judgeUrl(String url){ | ||
| 43 | + if (url == null) | ||
| 44 | + return; | ||
| 45 | + | ||
| 46 | + // rtmp:// | ||
| 47 | + if (url.length() < 8) { | ||
| 48 | + Log.e(TAG, "Input publish url error:" + url); | ||
| 49 | + return; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + if (!url.startsWith("rtmp://")) { | ||
| 53 | + Log.e(TAG, "Input publish url error:" + url); | ||
| 54 | + return; | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 时间 | ||
| 60 | + * @param currentTime | ||
| 61 | + * @return | ||
| 62 | + */ | ||
| 63 | + private String generateTime(long currentTime) { | ||
| 64 | + int totalSeconds = (int) (currentTime); | ||
| 65 | + | ||
| 66 | + int seconds = totalSeconds % 60; | ||
| 67 | + int minutes = (totalSeconds / 60) % 60; | ||
| 68 | + int hours = totalSeconds / 3600; | ||
| 69 | + | ||
| 70 | + if (hours > 0) { | ||
| 71 | + return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, | ||
| 72 | + seconds).toString(); | ||
| 73 | + } else { | ||
| 74 | + return String.format(Locale.US, "%02d:%02d", minutes, seconds) | ||
| 75 | + .toString(); | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | +} |
-
请 注册 或 登录 后发表评论