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