diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index 7f134441..e1962ad1 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -46,5 +46,10 @@ - diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 00000000..797acea5 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java index 48e03536..95a467d3 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java @@ -4,13 +4,17 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.IntEvaluator; import android.animation.ObjectAnimator; +import android.os.CountDownTimer; import android.os.Handler; +import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -33,10 +37,15 @@ import com.github.tvbox.osc.ui.adapter.LiveChannelGroupAdapter; import com.github.tvbox.osc.ui.adapter.LiveChannelItemAdapter; import com.github.tvbox.osc.ui.adapter.LiveSettingGroupAdapter; import com.github.tvbox.osc.ui.adapter.LiveSettingItemAdapter; +import com.github.tvbox.osc.ui.adapter.MyEpgAdapter; import com.github.tvbox.osc.ui.dialog.LivePasswordDialog; +import com.github.tvbox.osc.ui.tv.widget.ChannelListView; +import com.github.tvbox.osc.ui.tv.widget.Epginfo; import com.github.tvbox.osc.ui.tv.widget.ViewObj; import com.github.tvbox.osc.util.FastClickCheckUtil; import com.github.tvbox.osc.util.HawkConfig; +import com.github.tvbox.osc.util.urlhttp.CallBackUtil; +import com.github.tvbox.osc.util.urlhttp.UrlHttpUtil; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.lzy.okgo.OkGo; @@ -46,10 +55,16 @@ import com.orhanobut.hawk.Hawk; import com.owen.tvrecyclerview.widget.TvRecyclerView; import com.owen.tvrecyclerview.widget.V7LinearLayoutManager; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.Hashtable; import java.util.List; import java.util.Locale; @@ -78,16 +93,56 @@ public class LivePlayActivity extends BaseActivity { private LiveSettingItemAdapter liveSettingItemAdapter; private List liveSettingGroupList = new ArrayList<>(); + public static int currentChannelGroupIndex = 0; private Handler mHandler = new Handler(); private List liveChannelGroupList = new ArrayList<>(); - private int currentChannelGroupIndex = 0; private int currentLiveChannelIndex = -1; private int currentLiveChangeSourceTimes = 0; private LiveChannelItem currentLiveChannelItem = null; private LivePlayerManager livePlayerManager = new LivePlayerManager(); private ArrayList channelGroupPasswordConfirmed = new ArrayList<>(); +//EPG by 龍 + private static LiveChannelItem channel_Name = null; + private static Hashtable hsEpg = new Hashtable(); + private ChannelListView mRightEpgList; + private CountDownTimer countDownTimer; + private CountDownTimer countDownTimerRightTop; + private View ll_right_top_loading; + private View ll_right_top_huikan; + private View tv_tiploading; + private View divLoadEpg; + private View divLoadEpgleft; + RelativeLayout ll_epg; + TextView tv_channelnum; + TextView tip_chname; + TextView tip_epg1; + TextView tip_epg2; + TextView tv_srcinfo; + TextView tv_curepg_left; + TextView tv_nextepg_left; + private MyEpgAdapter myAdapter; + private TextView tv_right_top_tipnetspeed; + private TextView tv_right_top_channel_name; + private TextView tv_right_top_epg_name; + private TextView tv_right_top_type; + private ImageView iv_circle_bg; + private TextView tv_netspeedinfo; + private TextView tv_ad ; + private TextView tv_voluminfo ; + private TextView tv_shownum ; + private TextView txtNoEpg ; + private ImageView iv_back_bg; + + private ObjectAnimator objectAnimator; + private ObjectAnimator objectAnimator2; + + + + + + @Override protected int getLayoutResID() { return R.layout.activity_live_play; @@ -108,6 +163,37 @@ public class LivePlayActivity extends BaseActivity { tvTime = findViewById(R.id.tvTime); tvNetSpeed = findViewById(R.id.tvNetSpeed); + //EPG findViewById by 龍 + tip_chname = (TextView) findViewById(R.id.tv_channel_bar_name);//底部名称 + tv_channelnum = (TextView) findViewById(R.id.tv_channel_bottom_number); //底部数字 + tip_epg1 = (TextView) findViewById(R.id.tv_current_program_time);//底部EPG当前节目信息 + tip_epg2 = (TextView) findViewById(R.id.tv_next_program_time);//底部EPG当下个节目信息 + tv_srcinfo = (TextView) findViewById(R.id.tv_source);//线路状态 + tv_curepg_left = (TextView) findViewById(R.id.tv_current_program);//当前节目 + tv_nextepg_left= (TextView) findViewById(R.id.tv_current_program);//下一节目 + ll_epg = (RelativeLayout) findViewById(R.id.ll_epg); + tv_right_top_tipnetspeed = (TextView)findViewById(R.id.tv_right_top_tipnetspeed); + tv_right_top_channel_name = (TextView)findViewById(R.id.tv_right_top_channel_name); + tv_right_top_epg_name = (TextView)findViewById(R.id.tv_right_top_epg_name); + tv_right_top_type = (TextView)findViewById(R.id.tv_right_top_type); + iv_circle_bg = (ImageView) findViewById(R.id.iv_circle_bg); + iv_back_bg = (ImageView) findViewById(R.id.iv_back_bg); + tv_tiploading= (View) findViewById(R.id.ll_right_top_loading); + tv_shownum = (TextView) findViewById(R.id.tv_shownum); + txtNoEpg = (TextView) findViewById(R.id.txtNoEpg); + ll_right_top_loading = findViewById(R.id.ll_right_top_loading); + ll_right_top_huikan = findViewById(R.id.ll_right_top_huikan); + mRightEpgList = (ChannelListView) findViewById(R.id.lv_epg); + divLoadEpg = (View) findViewById(R.id.divLoadEpg); + divLoadEpgleft = (View) findViewById(R.id.divLoadEpgleft); + //右上角图片旋转 + objectAnimator = ObjectAnimator.ofFloat(iv_circle_bg,"rotation", 360.0f); + objectAnimator.setDuration(5000); + objectAnimator.setRepeatCount(-1); + objectAnimator.start(); + + + initVideoView(); initChannelGroupView(); initLiveChannelView(); @@ -116,6 +202,163 @@ public class LivePlayActivity extends BaseActivity { initLiveChannelList(); initLiveSettingGroupList(); } + //获取EPG并存储 // 百川epg DIYP epg 51zmt epg ------- 自建EPG格式输出格式请参考 51zmt + private List epgdata = new ArrayList<>(); + + //显示侧边EPG + private void showEpg(ArrayList arrayList){ + if (arrayList != null && arrayList.size() > 0) { + epgdata = arrayList; + int i=-1; + int size = epgdata.size() - 1; + while (size >= 0) { + if (new Date().compareTo(((Epginfo) epgdata.get(size)).startdateTime) >= 0) { + break; + } + size--; + } + i = size; + mRightEpgList.pos = i; + myAdapter = new MyEpgAdapter( epgdata,this,i); + mRightEpgList.setAdapter(myAdapter); + mRightEpgList.setSelection(i); + }else{ + Epginfo epgbcinfo = new Epginfo("暂无节目信息", "00:00", "23:59"); + arrayList.add(epgbcinfo); + epgdata=arrayList; + myAdapter = new MyEpgAdapter( epgdata,this,0); + mRightEpgList.setAdapter(myAdapter); + } + } + + public void getEpg() { + + final String channelName = channel_Name.getChannelName(); + Date date = new Date(); + SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd"); + String epgStringAddress ="http://epg.51zmt.top:8000/api/diyp/?ch="; + UrlHttpUtil.get(epgStringAddress + URLEncoder.encode(channelName.replace("+", "[add]").toString()) + "&date=" + timeFormat.format(date), new CallBackUtil.CallBackString() { + public void onFailure(int i, String str) { + } + public void onResponse(String paramString) { + + ArrayList arrayList = new ArrayList(); + + Log.d("返回的EPG信息", paramString); + try { + if (paramString.contains("epg_data")) { + final JSONArray jSONArray = new JSONObject(paramString).optJSONArray("epg_data"); + if (jSONArray != null) + for (int b = 0; b < jSONArray.length(); b++) { + JSONObject jSONObject = jSONArray.getJSONObject(b); + Epginfo epgbcinfo = new Epginfo(jSONObject.optString("title"), jSONObject.optString("start"), jSONObject.optString("end")); + arrayList.add(epgbcinfo); + Log.d("测试2", jSONObject.optString("title") + jSONObject.optString("start") + jSONObject.optString("end")); + } + } + + } catch (JSONException jSONException) { + jSONException.printStackTrace(); + } + showEpg(arrayList); + + if (!hsEpg.contains(channelName)) + hsEpg.put(channelName, arrayList); + showBottomEpg(); + } + }); + } + //显示底部EPG + private void showBottomEpg() { + if (channel_Name.getChannelName() != null) { + findViewById(R.id.ll_epg).setVisibility(View.VISIBLE); + ((TextView) findViewById(R.id.tv_channel_bar_name)).setText(channel_Name.getChannelName()); + ((TextView) findViewById(R.id.tv_channel_bottom_number)).setText("" + channel_Name.getChannelNum()); + ((TextView) findViewById(R.id.tv_current_program_time)).setText("咦,暂无信息"); + ((TextView) findViewById(R.id.tv_current_program_name)).setText(""); + ((TextView) findViewById(R.id.tv_next_program_time)).setText("开源测试软件,请勿商用以及播放违法内容!!!!"); + ((TextView) findViewById(R.id.tv_next_program_name)).setText(""); + if (hsEpg.containsKey(channel_Name.getChannelName())) { + ArrayList arrayList = (ArrayList) hsEpg.get(channel_Name.getChannelName()); + if (arrayList != null && arrayList.size() > 0) { + + int size = arrayList.size() - 1; + while (size >= 0) { + if (new Date().compareTo(((Epginfo) arrayList.get(size)).startdateTime) >= 0) { + ((TextView) findViewById(R.id.tv_current_program_time)).setText(((Epginfo) arrayList.get(size)).start + "--"+ ((Epginfo) arrayList.get(size)).end); + ((TextView) findViewById(R.id.tv_current_program_name)).setText(((Epginfo) arrayList.get(size)).title); + if (size != arrayList.size() - 1) { + ((TextView) findViewById(R.id.tv_next_program_time)).setText(((Epginfo) arrayList.get(size + 1)).start + "--"+ ((Epginfo) arrayList.get(size)).end); + ((TextView) findViewById(R.id.tv_next_program_name)).setText(((Epginfo) arrayList.get(size + 1)).title); + } + break; + } else { + size--; + } + } + } + } else { + getEpg(); + } + + if (countDownTimer != null) { + countDownTimer.cancel(); + } + + countDownTimer = new CountDownTimer(10000, 1000) {//底部epg隐藏时间设定 + public void onTick(long j) { + } + + public void onFinish() { + findViewById(R.id.ll_epg).setVisibility(View.GONE); + } + }; + countDownTimer.start(); + if (channel_Name == null || channel_Name.getSourceNum() <= 0) { + ((TextView) findViewById(R.id.tv_source)).setText("1/1"); + } else { + + ((TextView) findViewById(R.id.tv_source)).setText("[线路"+(channel_Name.getSourceIndex() + 1) + "/" + channel_Name.getSourceNum()+"]"); + } + + tv_right_top_channel_name.setText(channel_Name.getChannelName()); + tv_right_top_epg_name.setText(channel_Name.getChannelName()); + ll_right_top_loading.setVisibility(View.VISIBLE); + + if (countDownTimerRightTop != null) { + countDownTimerRightTop.cancel(); + } + + countDownTimerRightTop = new CountDownTimer(10000, 1000) { + public void onTick(long j) { + } + + public void onFinish() { + ll_right_top_loading.setVisibility(View.GONE); + } + }; + mHandler.post(mUpdateNetSpeedRun); + tv_right_top_tipnetspeed.setVisibility(View.VISIBLE); + + } + countDownTimerRightTop.start(); + } + + //频道列表 + public void divLoadEpgRight(View view) { + mRightEpgList.setVisibility(View.VISIBLE); + mChannelGroupView.setVisibility(View.GONE); + divLoadEpgleft.setVisibility(View.VISIBLE); + divLoadEpg.setVisibility(View.GONE); + } + //频道列表 + public void divLoadEpgLeft(View view) { + mRightEpgList.setVisibility(View.GONE); + mChannelGroupView.setVisibility(View.VISIBLE); + divLoadEpgleft.setVisibility(View.GONE); + divLoadEpg.setVisibility(View.VISIBLE); + } + @Override public void onBackPressed() { @@ -298,7 +541,7 @@ public class LivePlayActivity extends BaseActivity { private boolean playChannel(int channelGroupIndex, int liveChannelIndex, boolean changeSource) { if ((channelGroupIndex == currentChannelGroupIndex && liveChannelIndex == currentLiveChannelIndex && !changeSource) || (changeSource && currentLiveChannelItem.getSourceNum() == 1)) { - showChannelInfo(); + // showChannelInfo(); return true; } mVideoView.release(); @@ -309,8 +552,12 @@ public class LivePlayActivity extends BaseActivity { Hawk.put(HawkConfig.LIVE_CHANNEL, currentLiveChannelItem.getChannelName()); livePlayerManager.getLiveChannelPlayer(mVideoView, currentLiveChannelItem.getChannelName()); } + + channel_Name = currentLiveChannelItem; + getEpg(); + mVideoView.setUrl(currentLiveChannelItem.getUrl()); - showChannelInfo(); + // showChannelInfo(); mVideoView.start(); return true; } @@ -937,6 +1184,7 @@ public class LivePlayActivity extends BaseActivity { public void run() { if (mVideoView == null) return; tvNetSpeed.setText(String.format("%.2fMB/s", (float)mVideoView.getTcpSpeed() / 1024.0 / 1024.0)); + tv_right_top_tipnetspeed.setText(String.format("%.2fKB/s",(float)mVideoView.getTcpSpeed()/1024.0)); mHandler.postDelayed(this, 1000); } }; diff --git a/app/src/main/java/com/github/tvbox/osc/ui/adapter/MyEpgAdapter.java b/app/src/main/java/com/github/tvbox/osc/ui/adapter/MyEpgAdapter.java new file mode 100644 index 00000000..29fe0160 --- /dev/null +++ b/app/src/main/java/com/github/tvbox/osc/ui/adapter/MyEpgAdapter.java @@ -0,0 +1,96 @@ +package com.github.tvbox.osc.ui.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import com.github.tvbox.osc.R; +import com.github.tvbox.osc.ui.tv.widget.AudioWaveView; +import com.github.tvbox.osc.ui.tv.widget.Epginfo; + +import java.util.Date; +import java.util.List; + +public class MyEpgAdapter extends BaseAdapter { + + private List data; + private Context context; + public static float fontSize=20; + private int defaultSelection = 0; + private int defaultShiyiSelection = 0; + + public MyEpgAdapter(List data, Context context, int i ) { + this.data = data; + this.context = context; + this.defaultSelection = i; + } + + + public void setSelection(int i) { + this.defaultSelection = i; + notifyDataSetChanged(); + } + + public void setShiyiSelection(int i) { + this.defaultShiyiSelection = i; + notifyDataSetChanged(); + } + + public void setFontSize(float f) { + fontSize = f; + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return data.size(); + } + + @Override + public Object getItem(int i) { + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + if(view ==null){ + view = LayoutInflater.from(context).inflate(R.layout.epglist_item,viewGroup,false); + } + TextView textview = (TextView)view.findViewById(R.id.tv_epg_name); + TextView timeview = (TextView)view.findViewById(R.id.tv_epg_time); + AudioWaveView wqddg_AudioWaveView = (AudioWaveView)view.findViewById(R.id.wqddg_AudioWaveView); + wqddg_AudioWaveView.setVisibility(View.GONE); + if(i < data.size()){ + + textview.setText(data.get(i).title); + timeview.setText(data.get(i).start + "--" + data.get(i).end); + textview.setTextColor(Color.WHITE) ; + timeview.setTextColor(Color.WHITE) ; + Log.e("roinlong", "getView: "+ i); + if(i == this.defaultSelection){ + wqddg_AudioWaveView.setVisibility(View.VISIBLE); + textview.setTextColor(Color.rgb(0, 153, 255)) ; + timeview.setTextColor(Color.rgb(0, 153, 255)) ; + textview.setFreezesText(true); + timeview.setFreezesText(true); + }else { + wqddg_AudioWaveView.setVisibility(View.GONE); + } + + } + return view; + } +} + + diff --git a/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/ChannelListView.java b/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/ChannelListView.java new file mode 100644 index 00000000..09b9ee31 --- /dev/null +++ b/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/ChannelListView.java @@ -0,0 +1,53 @@ +package com.github.tvbox.osc.ui.tv.widget; + + + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.widget.ListView; + +import com.github.tvbox.osc.ui.activity.LivePlayActivity; + +public class ChannelListView extends ListView { + DataChangedListener dataChangedListener; + public int pos= LivePlayActivity.currentChannelGroupIndex; + private int y; + + public ChannelListView(Context context) { + super(context); + } + public ChannelListView(Context context, AttributeSet attrs) { + super(context, attrs); + } + public ChannelListView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + public void setSelect(int position,int y) { + super.setSelection(position); + pos=position; + this.y=y; + } + @Override + protected void onFocusChanged(boolean gainFocus, int direction, + Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + if (gainFocus) { + setSelectionFromTop(pos, y); + } + } + + + @Override + protected void handleDataChanged() { + super.handleDataChanged(); + if(dataChangedListener!=null)dataChangedListener.onSuccess(); + } + public void setDataChangedListener(DataChangedListener dataChangedListener) { + this.dataChangedListener = dataChangedListener; + } + public interface DataChangedListener{ + public void onSuccess(); + } + +} diff --git a/app/src/main/res/drawable/bg_channel_list.xml b/app/src/main/res/drawable/bg_channel_list.xml new file mode 100644 index 00000000..46950af3 --- /dev/null +++ b/app/src/main/res/drawable/bg_channel_list.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/item_bg_selector_left.xml b/app/src/main/res/drawable/item_bg_selector_left.xml new file mode 100644 index 00000000..e87118ff --- /dev/null +++ b/app/src/main/res/drawable/item_bg_selector_left.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/app/src/main/res/drawable/item_bg_selector_right.xml b/app/src/main/res/drawable/item_bg_selector_right.xml new file mode 100644 index 00000000..5b4ecca7 --- /dev/null +++ b/app/src/main/res/drawable/item_bg_selector_right.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/item_right_bg.xml b/app/src/main/res/drawable/item_right_bg.xml new file mode 100644 index 00000000..9f6547f7 --- /dev/null +++ b/app/src/main/res/drawable/item_right_bg.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/shape_user_search.xml b/app/src/main/res/drawable/shape_user_search.xml new file mode 100644 index 00000000..858dfd9e --- /dev/null +++ b/app/src/main/res/drawable/shape_user_search.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_live_play.xml b/app/src/main/res/layout/activity_live_play.xml index abe3a931..e56005e8 100644 --- a/app/src/main/res/layout/activity_live_play.xml +++ b/app/src/main/res/layout/activity_live_play.xml @@ -7,57 +7,218 @@ + android:layout_height="match_parent" > - + - + - + - - + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -65,7 +226,6 @@ android:id="@+id/mSettingItemView" android:layout_width="180mm" android:layout_height="match_parent" - android:background="@color/color_66000000" android:paddingLeft="5mm" android:paddingTop="10mm" android:paddingRight="5mm" @@ -85,7 +245,6 @@ android:id="@+id/mSettingGroupView" android:layout_width="180mm" android:layout_height="match_parent" - android:background="@color/color_66000000" android:paddingLeft="5mm" android:paddingTop="10mm" android:paddingRight="5mm" @@ -136,4 +295,338 @@ android:textColor="@android:color/white" android:textSize="22mm" android:visibility="gone" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a5b0b899..978551ba 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,6 +3,7 @@ #6200EE #3700B3 #03DAC5 + #ffce7900 #1890FF #FF6600 #00FF0A @@ -29,4 +30,6 @@ #33ffffff #4D000000 #59353744 + #66FF0057 + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ee105052..367e34af 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -39,4 +39,16 @@ true true + + diff --git a/gradle.properties b/gradle.properties index 19dc3e60..616c0175 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m +org.gradle.jvmargs=-Xmx1560m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects