package com.yidianling.course.coursePlay import android.annotation.SuppressLint import android.app.AlertDialog import android.content.Intent import android.content.res.Configuration import android.graphics.Color import android.os.Build import android.os.Handler import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.OrientationHelper import android.text.TextUtils import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.alibaba.android.arouter.facade.annotation.Route import com.bumptech.glide.Glide import com.dou361.ijkplayer.widget.PlayStateParams import com.dou361.ijkplayer.widget.PlayerView import com.lzf.easyfloat.enums.ShowPattern import com.lzf.easyfloat.permission.PermissionUtils import com.ydl.media.audio.AudioPlayer import com.ydl.media.audio.utils.PlayProgressUtil import com.ydl.media.view.PlayTypeEnum import com.ydl.media.view.PlayerFloatHelper import com.ydl.ydl_image.module.GlideApp import com.ydl.ydl_router.manager.YDLRouterManager import com.ydl.ydlcommon.adapter.CommonRecyclerAdapter import com.ydl.ydlcommon.base.BaseActivity import com.ydl.ydlcommon.bean.ShareData import com.ydl.ydlcommon.data.PlatformDataManager import com.ydl.ydlcommon.modular.ModularServiceManager import com.ydl.ydlcommon.router.IYDLRouterConstant import com.ydl.ydlcommon.router.YdlCommonRouterManager import com.ydl.ydlcommon.utils.ScreenUtil import com.ydl.ydlcommon.utils.StatusBarUtils import com.ydl.ydlcommon.utils.Utils import com.ydl.ydlcommon.view.BaseViewHolder import com.ydl.ydlcommon.view.dialog.CommonDialog import com.ydl.ydlcommon.view.dialog.YDLShareDialog import com.yidianling.common.tools.RxImageTool import com.yidianling.common.tools.ToastUtil import com.yidianling.course.BuildConfig import com.yidianling.course.R import com.yidianling.course.bean.CourseMediaBean import com.yidianling.course.bean.CourseMediaDetailBean import com.yidianling.course.coursePlay.presenter.CoursePlayPresenter import com.yidianling.course.router.CourseIn import com.yidianling.course.widget.VideoFloatHelper import com.yidianling.ydl_pay.common.CommonPayDialog import kotlinx.android.synthetic.main.activity_course_play.* import org.json.JSONException import org.json.JSONObject import java.util.* /** * 课程播放页面 */ @Route(path = "/course/play") class CoursePlayActivity : BaseActivity() { private val ROUTER_PARAMS = "routerParam" /*******************播放器模块*******************/ //音视频模块 var playAudioView: PlayViewInterface? = null var playVideoView: PlayViewInterface? = null //当前播放模式 0音频播放 1视频播放 var play_type = 0 /**********************中间内容模块************************/ var headview: CourseHeadView? = null var adapter: CommonRecyclerAdapter<CourseMediaBean>? = null //播放列表 var playList: ArrayList<CourseMediaBean> = ArrayList() var presenter: CoursePlayPresenter? = null var index = 0 //当前播放下标 //课程id var course_id = 0 //是否全屏 0:否 1 全屏 var fullScreen = 0 var courPlayBean: CourseMediaDetailBean? = null //外部选中要播放的音/视频文件地址 private var receiverPlayUrl: String? = "" var from: Int = 0 private var handler = Handler() //视频播放器view var videoView: PlayerView? = null //视频是否在播放 var isVideoPlay = false //TODO 播放状态统一 var isShowAnim = true //是否是悬浮窗进入 private var isFromFloatView = false private var isCancelNetCheck = false override fun layoutResId(): Int { return R.layout.activity_course_play } override fun initDataAndEvent() { //获取参数 getParam() if (course_id == 0) { ToastUtil.toastShort("参数错误") finish() } presenter = CoursePlayPresenter(this) initView() initWindows() initData() nestedScrollView.scrollTo(0, 0) } fun initView() { iv_back.setOnClickListener { onBackPressed() } iv_share.setOnClickListener { //分享 share(courPlayBean?.courseExtra?.shareData) } StatusBarUtils.setWindowStatusBarColor(mContext, R.color.transparent) tv_write_comment.setOnClickListener { if (!Utils.isFastClick()) { showVideoFloatView() CourseCommentActivity.startActivity(this@CoursePlayActivity, course_id.toString()) } } text_price?.setOnClickListener { //参加课程 addCourseOrder() } recy_list?.isNestedScrollingEnabled = false recy_list?.layoutManager = LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false ) adapter = CommonRecyclerAdapter<CourseMediaBean>(recy_list, R.layout.item_course_playlist_item) .setBindDataCallback(object : CommonRecyclerAdapter.BindDataCallback<CourseMediaBean> { override fun bindDatabindData( holder: BaseViewHolder, bean: CourseMediaBean, position: Int ) { var gifView: ImageView = holder.getView(R.id.gifView) var playView: ImageView = holder.getView(R.id.ic_play_view) var bodyView: LinearLayout = holder.getView(R.id.lin_body) if (index == position) { gifView.visibility = View.VISIBLE playView.visibility = View.GONE bodyView.setBackgroundColor(this@CoursePlayActivity.resources.getColor(R.color.course_color_F8FCFF)) if (isShowAnim) { Glide.with(this@CoursePlayActivity).asGif() .load(R.drawable.course_music).into(gifView) } else { Glide.with(this@CoursePlayActivity).asBitmap() .load(R.drawable.course_music).into(gifView) } holder.setTextColor( R.id.text_title, this@CoursePlayActivity.resources.getColor(R.color.platform_main_theme) ) } else { gifView.visibility = View.GONE playView.visibility = View.VISIBLE bodyView.setBackgroundColor(this@CoursePlayActivity.resources.getColor(R.color.white)) if (courPlayBean?.courseExtra?.isBuy!!) { GlideApp.with(this@CoursePlayActivity) .load(R.drawable.course_ico_kcml_play).into(playView) } else { if (bean.isDemo) { GlideApp.with(this@CoursePlayActivity) .load(R.drawable.course_ico_kcml_play) .into(playView) } else { GlideApp.with(this@CoursePlayActivity) .load(R.drawable.course_ico_kcml_lock) .into(playView) } } holder.setTextColor( R.id.text_title, this@CoursePlayActivity.resources.getColor(R.color.course_color_FF000000) ) } var test: TextView = holder.getView(R.id.text_test) //试听标签 if (bean.isDemo) { test.visibility = View.VISIBLE } else { test.visibility = View.GONE } holder.setText(R.id.text_title, bean.title) holder.setOnClickListener(R.id.lin_body) { if (position < 0) { return@setOnClickListener } if (index == position) { } else { if (!bean.isDemo && !courPlayBean!!.courseExtra.isBuy) { CommonDialog(this@CoursePlayActivity) .setMessage("\n购买课程,获取完整课程内容\n") .setLeftOnclick("放弃") { } .setRightClick("购买") { //跳转支付页 addCourseOrder() } .setCancelAble(false) .show() return@setOnClickListener } PlayProgressUtil.saveProgress( this@CoursePlayActivity, playList[index].url, 0 ) updatePlayingListStatus(position) // if (playList[index].mediaType == 2) { // play_type = 1 // (playVideoView as CoursePlayItemViewVideo)?.play(position) // } // if (playList[index].mediaType == 1) { // play_type = 0 // if (RxNetTool.isWifi(this@CoursePlayActivity)) { // (playAudioView as CoursePlayItemViewAudio).playView!!.play( // position // ) // } else { // if ((playAudioView as CoursePlayItemViewAudio).hasEnsureNetStatus) { // (playAudioView as CoursePlayItemViewAudio).playView!!.play( // position // ) // } else { // (playAudioView as CoursePlayItemViewAudio).setData( // position, // playList, // courPlayBean!!.courseExtra, // from // ) // } // } // } // adapter?.notifyDataSetChanged() } } } }) headview = CourseHeadView(this) //添加头部和底部view adapter!!.addHeadView(headview) recy_list.adapter = adapter } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) var new_course_id = 0 if (intent != null) { new_course_id = intent.getIntExtra("course_id", 0) } if (new_course_id == 0) { ToastUtil.toastShort("参数错误") finish() } if (new_course_id != course_id) { course_id = new_course_id initData() } } /** * 获取路由传递的参数 */ private fun getParam() { if (null == intent) { return } if (intent.hasExtra(ROUTER_PARAMS)) { //路由传递的入参 val json = intent.getStringExtra(ROUTER_PARAMS) try { val jsonObject = JSONObject(json) //课程ID course_id = jsonObject.getInt(IYDLRouterConstant.EXTRA_ID) } catch (e: JSONException) { e.printStackTrace() } return } //正常跳转所传参数 course_id = intent.getIntExtra("course_id", 0) //mediaType是服务端新定义的媒体类型,1.音频 2.视频 ,与本地定义类型不同,先不改本地定义数据类型 var mediaType = intent.getStringExtra("mediaType") if (TextUtils.equals(mediaType, "1")) { play_type = 0 } else if (TextUtils.equals(mediaType, "2")) { play_type = 1 } fullScreen = intent.getIntExtra("fullScreen", 0) receiverPlayUrl = intent.getStringExtra("coursePlayUrl") isFromFloatView = intent.getBooleanExtra("isFromFloatView", false) if (!TextUtils.isEmpty(receiverPlayUrl) && isFromFloatView) { isCancelNetCheck = true } try { if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_COURSE && AudioPlayer.get().isPlaying && TextUtils.isEmpty(receiverPlayUrl) ) { receiverPlayUrl = AudioPlayer.get().playMusic?.path } } catch (e: Exception) { } from = intent.getIntExtra("from", 0) } private fun initWindows() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { val window = window //获取状态栏高度 var statusBarheight: Int = ScreenUtil.getStatusBarHeight(mContext) //设置边距 setMargins( title_bar_layout, RxImageTool.dp2px(15f), statusBarheight, RxImageTool.dp2px(15f), 0 ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.statusBarColor = Color.TRANSPARENT window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) } else { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) } } } private fun setMargins(v: View?, l: Int, t: Int, r: Int, b: Int) { if (v != null) { if (v.layoutParams is ViewGroup.MarginLayoutParams) { val p = v.layoutParams as ViewGroup.MarginLayoutParams p.setMargins(l, t, r, b) v.requestLayout() } } } private fun initData() { //获取数据 presenter?.getInitData(course_id) } //跟新view显示 @SuppressLint("SetTextI18n") fun updateView(bean: CourseMediaDetailBean) { courPlayBean = bean playList.clear() setPlayList(bean) if (!TextUtils.isEmpty(receiverPlayUrl)) { for ((index, element) in playList.withIndex()) { if (TextUtils.equals(receiverPlayUrl, element.url) || TextUtils.equals( receiverPlayUrl!!.replace( "http", "https" ), element.url ) ) { this@CoursePlayActivity.index = index } } } play_type = if (playList[index].mediaType == 1) { 0 } else { 1 } try { if (play_type == 1) { //视频播放销毁音频服务 AudioPlayer.get().stopPlayer() } if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_CONFIDE || PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_FM) { if (AudioPlayer.get().isPlaying) { AudioPlayer.get().stopPlayer() } } } catch (e: Exception) { e.printStackTrace() } // if (play_type == 1) {//视频 // playVideoView = CoursePlayItemViewVideo.create(this, play_type) // (playVideoView as CoursePlayItemViewVideo).hasEnsureNetStatus = isCancelNetCheck // frame_video_play.addView(playVideoView as CoursePlayItemViewVideo) // } else {//音频 // playAudioView = CoursePlayItemViewAudio.create(this, play_type) // (playAudioView as CoursePlayItemViewAudio).hasEnsureNetStatus = isCancelNetCheck // frame_audio_play.addView(playAudioView as CoursePlayItemViewVideo) // } //专家简介部分 headview?.setData(bean.courseExtra) //视频 playVideoView = CoursePlayItemViewVideo.create(this, play_type) (playVideoView as CoursePlayItemViewVideo).hasEnsureNetStatus = isCancelNetCheck frame_video_play.addView(playVideoView as CoursePlayItemViewVideo) //音频 playAudioView = CoursePlayItemViewAudio.create(this, play_type) (playAudioView as CoursePlayItemViewAudio).hasEnsureNetStatus = isCancelNetCheck frame_audio_play.addView(playAudioView as CoursePlayItemViewAudio) if (play_type == 0) { frame_audio_play.visibility = View.VISIBLE frame_video_play.visibility = View.GONE } else { frame_video_play.visibility = View.VISIBLE frame_audio_play.visibility = View.GONE } playAudioView?.setData(index, playList, bean.courseExtra, from, play_type == 0) playVideoView?.setData(index, playList, bean.courseExtra, from, play_type == 1) if (videoView != null && play_type == 1 && fullScreen == 1) { videoView!!.toggleFullScreen() videoView!!.setNetWorkTypeTie(false) videoView!!.startPlay() } tv_title_full.text = bean.courseExtra.title text_price.text = "立即购买 ¥" + bean.courseExtra.applyFee if (bean.courseExtra.isBuy) { //已报名 text_price.visibility = View.GONE tv_write_comment.visibility = View.VISIBLE //评论数量是大于 1,表示已经已经评论过,不再显示底部的评论区域 if (bean.courseExtra.userCommentNum >= 1) { rl_write_bottom.visibility = View.GONE } } else { //未报名 text_price.visibility = View.VISIBLE tv_write_comment.visibility = View.GONE } } //设置播放列表数据 private fun setPlayList(bean: CourseMediaDetailBean) { if (bean.voiceSample.courseMedia.isNotEmpty()) { for (voiceSampleData in bean.voiceSample.courseMedia) { voiceSampleData.isDemo = true playList.add(voiceSampleData) } } if (bean.voiceWhole.courseMedia.isNotEmpty()) { for (voiceCourseData in bean.voiceWhole.courseMedia) { playList.add(voiceCourseData) } } adapter!!.update(playList) } fun updatePlayingListStatus(index: Int) { if (index < playList.size && this.index != index) { if (!playList[index].isDemo && !courPlayBean!!.courseExtra.isBuy) { if (AudioPlayer.get().isPlaying) { AudioPlayer.get().playPause() } if (videoView != null) { videoView?.pausePlay() } CommonDialog(this@CoursePlayActivity) .setMessage("\n购买课程,获取完整课程内容\n") .setLeftOnclick("放弃") { } .setRightClick("购买") { //跳转支付页 addCourseOrder() } .setCancelAble(false) .show() return } if (playList[index].mediaType == 1) { play_type = 0 frame_video_play.visibility = View.GONE frame_audio_play.visibility = View.VISIBLE (playAudioView as CoursePlayItemViewAudio).playView?.play( index ) if (videoView != null) { videoView?.pausePlay() } } if (playList[index].mediaType == 2) { play_type = 1 frame_video_play.visibility = View.VISIBLE frame_audio_play.visibility = View.GONE if (AudioPlayer.get().isPlaying) { AudioPlayer.get().playPause() } (playVideoView as CoursePlayItemViewVideo)?.play(index) } this.index = index adapter?.notifyDataSetChanged() } } fun showLoadingDialog() { showProgressDialog(null) } fun dismissLoadingDialog() { dismissProgressDialog() } //参加课程 fun addCourseOrder() { if (course_id == 0) { ToastUtil.toastShort("请退出页面重试") return } val userInfo = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo() if (userInfo == null || TextUtils.isEmpty(userInfo.userId)) { CourseIn.loginByOneKeyLogin(mContext,true) return } val build = CommonPayDialog.Build(mContext) .setCourseId(course_id.toString()) .setToken(userInfo.token) .setUid(userInfo.userId) .setFfrom(PlatformDataManager.getRam().getChannelName()) .setListener(object : CommonPayDialog.OnPayResultListener { override fun onSuccesed() { //刷新界面 initData() } override fun onFailed() { } }) .setIsTestEnvironment(BuildConfig.DEBUG) build.build().show() } /** * 分享 */ private fun share(share: ShareData?) { if (share == null) { ToastUtil.toastShort("缺少参数") return } val dialog = YDLShareDialog.style1( this, share.title, share.share_url, share.desc, share.cover, "", "" ) dialog.setCallBack(object : YDLShareDialog.ICallBack { override fun callBack(type: Int) { if (1 == type) { ModularServiceManager.getPlatformUserService() if (CourseIn.loginByOneKeyLogin(this@CoursePlayActivity,true)) { //分享到心事动态 toTrend(share) } } } }) dialog.show(fragmentManager, "lose") } private fun toTrend(share: ShareData) { var url = if (TextUtils.isEmpty(share.url)) share.share_url else share.url CourseIn.getDynamicService() .publishArticleToTrend(this@CoursePlayActivity, url!!, share.cover!!, share.title!!) } override fun onPause() { super.onPause() videoView?.onPause() playVideoView?.onPause() playAudioView?.onPause() } override fun onResume() { super.onResume() playVideoView?.onResume() playAudioView?.onResume() if (PlayerFloatHelper.isShow(this)) { PlayerFloatHelper.removeView(this) } } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) if (play_type == 1) { if (newConfig.screenHeightDp > newConfig.screenWidthDp) { //显示底部评论按钮 rl_write_bottom.visibility = View.VISIBLE tv_title_full.visibility = View.GONE nestedScrollView.isVerticalFadingEdgeEnabled = true nestedScrollView.isVerticalScrollBarEnabled = true recy_list.visibility = View.VISIBLE videoView?.hideBack(true) } else { rl_write_bottom.visibility = View.GONE tv_title_full.visibility = View.VISIBLE nestedScrollView.isVerticalFadingEdgeEnabled = false nestedScrollView.isVerticalScrollBarEnabled = false recy_list.visibility = View.GONE videoView?.hideBack(false) } videoView?.onConfigurationChanged(newConfig) handler.postDelayed({ if (newConfig.screenHeightDp > newConfig.screenWidthDp) { videoView?.fullScreenView!!.setImageResource(R.drawable.course_ico_play_float_full) } else { videoView?.fullScreenView!!.setImageResource(R.drawable.ico_play_minify) } }, 300) } } override fun onBackPressed() { if (showVideoFloatView()) { super.onBackPressed() } } fun showVideoFloatView(): Boolean { if (play_type == 0) { if (AudioPlayer.get().isPlaying && PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_COURSE) { AudioPlayer.get().playMusic?.coverPath = courPlayBean?.courseExtra?.pic AudioPlayer.get().playMusic?.artist = courPlayBean?.courseExtra?.doctorName PlayerFloatHelper.playTempData.clear() val hashMap = HashMap<String, String>() hashMap["course_id"] = course_id.toString() PlayerFloatHelper.playTempData.putAll(hashMap) } } else { if (videoView?.onBackPressed() == true) { return false } if (isVideoPlay) { var status = Utils.getValue(videoView, "status") //视频课程正在播放中 if (status == PlayStateParams.STATE_PLAYING) { VideoFloatHelper.setVideoInfo( course_id.toString(), (playVideoView as CoursePlayItemViewVideo).videoUrl!!, true ) VideoFloatHelper.defaultShowPattern = ShowPattern.FOREGROUND checkPermission() } } } return true } /** * 检测浮窗权限是否开启,若没有给与申请提示框(非必须,申请依旧是EasyFloat内部内保进行) */ private fun checkPermission() { if (PermissionUtils.checkPermission(this)) { VideoFloatHelper.showVideoFloat(this) } else { AlertDialog.Builder(this) .setMessage("使用浮窗功能,需要您授权悬浮窗权限。") .setPositiveButton("去开启") { _, _ -> VideoFloatHelper.showVideoFloat(this) } .setNegativeButton("取消") { _, _ -> ToastUtil.toastLong( this, "App正常工作需要内部存储使用权限,请开启" ) } .show() } } override fun onDestroy() { super.onDestroy() videoView?.onDestroy() playAudioView?.onDestroy() playVideoView?.onDestroy() playAudioView = null playVideoView = null } }