Newer
Older
VipVideo / app / src / main / java / me / bello / viptv / ui / PlayActivity.java
bello on 15 Jan 2021 18 KB 增加下载缓存功能
package me.bello.viptv.ui;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Base64;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.Toast;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dueeeke.videocontroller.StandardVideoController;
import com.dueeeke.videocontroller.component.CompleteView;
import com.dueeeke.videocontroller.component.ErrorView;
import com.dueeeke.videocontroller.component.GestureView;
import com.dueeeke.videocontroller.component.TitleView;
import com.dueeeke.videocontroller.component.VodControlView;
import com.dueeeke.videoplayer.player.VideoView;
import com.github.dfqin.grantor.PermissionListener;
import com.github.dfqin.grantor.PermissionsUtil;
import com.uuzuche.lib_zxing.activity.CaptureActivity;
import com.uuzuche.lib_zxing.activity.CodeUtils;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import me.bello.viptv.R;
import me.bello.viptv.SiteData;
import me.bello.viptv.adapter.TVChannelAdapter;
import me.bello.viptv.app.AppConst;
import me.bello.viptv.http.ApiRequest;
import me.bello.viptv.util.down.Downloader;

/**
 * @Info
 * @Author Bello
 * @Time 21-1-11 上午9:56
 * @Ver
 */
public class PlayActivity extends AppCompatActivity implements View.OnClickListener {
    private Context mContext;
    private VideoView videoView;
    private FrameLayout frameLayout;
    private ImageView sendImg, downImg, changeImg;
    private String playUrl = "";
    private String type = "";
    private List<SiteData> channelList = new ArrayList<>();
    private MyHandler myHandler = new MyHandler();
    private List<SiteData> fromList = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play);
        mContext = this;

        playUrl = getIntent().getStringExtra("url");
        type = getIntent().getStringExtra("type");

        initUI();

        getDefaultChannel();

    }

    /**
     * 初始化频道数据
     */
    private void getDefaultChannel() {
        SharedPreferences sharedPreferences = getSharedPreferences("info", 0);
        String tv = sharedPreferences.getString("tv", "");
        if (tv.isEmpty()) {
            new ApiRequest().getTvChannel(mContext, new ApiRequest.OnCompleteListener() {
                @Override
                public void result(boolean success) {
                    if (success){
                        getDefaultChannel();
                    }
                }
            });
        } else {
            JSONArray array = JSONArray.parseArray(tv);
            channelList.clear();
            for (int i = 0; i < array.size(); i++) {
                JSONObject obj = array.getJSONObject(i);
                channelList.add(new SiteData(0, obj.getString("name"), obj.getString("url")));
            }

            if (type.equals(AppConst.TYPE_TV)) {
                String[] s = channelList.get(0).getSite().split(",");
                fromList.clear();
                for (int i = 0; i < s.length; i++) {
                    fromList.add(new SiteData(i == 0 ? 1 : 0, "线路" + (i + 1), s[i]));
                }
                playUrl = fromList.get(0).getSite();
                channelList.get(0).setIconId(1);
                playVideo();
            }

            new ApiRequest().getTvChannel(mContext, new ApiRequest.OnCompleteListener() {
                @Override
                public void result(boolean success) {
                }
            });
        }
    }

    private void initUI() {
        frameLayout = findViewById(R.id.frame_layout);
        frameLayout.setOnClickListener(this);
        sendImg = findViewById(R.id.send_image);
        sendImg.setOnClickListener(this);
        downImg = findViewById(R.id.down_image);
        downImg.setOnClickListener(this);
        changeImg = findViewById(R.id.from_image);
        changeImg.setOnClickListener(this);

        // 初始化videoView
        videoView = findViewById(R.id.video_view);
        StandardVideoController controller = new StandardVideoController(this);
        controller.setEnableOrientation(true);
        //滑动控制视图
        GestureView gestureControlView = new GestureView(this);
        controller.addControlComponent(gestureControlView);
        //自动完成播放界面
        controller.addControlComponent(new CompleteView(this));
        //错误界面
        controller.addControlComponent(new ErrorView(this));
        //标题栏
        TitleView titleView = new TitleView(this);
        //点播控制条
        VodControlView vodControlView = new VodControlView(this);
        //是否显示底部进度条。默认显示
//                vodControlView.showBottomProgress(false);
        controller.addControlComponent(vodControlView);
        controller.addControlComponent(titleView);
        //设置控制器
        videoView.setVideoController(controller);
        videoView.setOnStateChangeListener(new VideoView.OnStateChangeListener() {
            @Override
            public void onPlayerStateChanged(int playerState) {
            }

            @Override
            public void onPlayStateChanged(int playState) {
                // TV播放报错,自动换源
                /*if (playState == -1 && type.equals(AppConst.TYPE_TV) && tvPlayPosition < fromList.length - 1) {
                    tvPlayPosition += 1;
                    playUrl = fromList[tvPlayPosition];
                    playVideo();
                }*/
            }
        });
        //开始播放,不调用则不自动播放
//        videoView.start();
        playVideo();

    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.frame_layout:
                showChannelShade();
                break;
            case R.id.send_image:
                push(playUrl);
                break;
            case R.id.down_image:
                if (playUrl.contains(".mp4")) {
                    toast(mContext, "正在加载缓存...");
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            myHandler.sendEmptyMessageDelayed(CODE_1, 2000);
                            new Downloader(mContext, playUrl).start();

                        }
                    }).start();
                }
                break;
            case R.id.from_image:
                changeTvFrom();
                break;
        }
    }


    /**
     * 显示TV频道列表
     */
    private void showChannelShade() {
        if (type.equals(AppConst.TYPE_VIDEO)) {
            return;
        }
        View view = LayoutInflater.from(mContext).inflate(R.layout.pop_tv_channel, null, false);

        PopupWindow popupWindow = new PopupWindow(view, 400,
                ViewGroup.LayoutParams.MATCH_PARENT, true);
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        popupWindow.setAnimationStyle(R.style.popLeftAnim);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setTouchable(true);
        popupWindow.setFocusable(true);
        popupWindow.showAtLocation(frameLayout, Gravity.LEFT, 0, 0);

        ListView list = view.findViewById(R.id.tv_list_view);
        TVChannelAdapter adapter = new TVChannelAdapter(mContext, channelList);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String[] s = channelList.get(position).getSite().split(",");
                fromList.clear();
                for (int i = 0; i < s.length; i++) {
                    fromList.add(new SiteData(i==0?1:0, "线路"+(i+1), s[i]));
                }
                playUrl = fromList.get(0).getSite();
                type = AppConst.TYPE_TV;
                playVideo();

                for (int i = 0; i < channelList.size(); i++) {
                    if (position == i) {
                        channelList.get(i).setIconId(1);
                    } else {
                        channelList.get(i).setIconId(0);
                    }
                }

                popupWindow.dismiss();
            }
        });

        // 窗体背景半透明
        final WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.5f;
        getWindow().setAttributes(lp);

        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });

        int position = 0;
        for (int i = 0; i < channelList.size(); i++) {
            if (channelList.get(i).getIconId() == 1) {
                position = i;
            }
        }

        list.setSelection(position);
        list.smoothScrollToPosition(position);
    }


    /**
     * 播放视频
     */
    private void playVideo() {
        if (type.equals(AppConst.TYPE_VIDEO)) {
            frameLayout.setVisibility(View.GONE);
            changeImg.setVisibility(View.GONE);
            if (playUrl.contains(".mp4")) {
                downImg.setVisibility(View.VISIBLE);
            } else {
                downImg.setVisibility(View.GONE);
            }
        } else {
            frameLayout.setVisibility(View.VISIBLE);
//            if (tvPlayArray != null && tvPlayArray.length > 1) {
                changeImg.setVisibility(View.VISIBLE);
            downImg.setVisibility(View.GONE);
//            } else {
//                changeImg.setVisibility(View.GONE);
//            }
        }
        Log.e("play", "=====> " + playUrl);
        videoView.release();
        //设置视频地址
        videoView.setUrl(playUrl);
        //开始播放,不调用则不自动播放
        videoView.start();
    }


    /**
     * 把解析出来的视频地址推送到电视上
     * @param url 视频url
     */
    private void push(final String url) {
        SharedPreferences sharedPreferences = getSharedPreferences("data", 0);
        String ip = sharedPreferences.getString("ip", "");
        if (ip.isEmpty()) {
            toast(mContext, "请先绑定要推送到的设备");
            requestCamera();
            return;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.what = 0;
                try {

                    String uri = "http://" + ip + ":10868/pushVideoUrl?type=" + type + "&url=" + Base64.encodeToString(url.getBytes("UTF-8"), Base64.DEFAULT);
                    Document document = Jsoup.connect(uri).validateTLSCertificates(false)
                            .ignoreContentType(true)
                            .timeout(5000).get();

                    if (document != null && document.text().equals("success")) {
                        msg.obj = "发送成功";
                    } else {
                        msg.obj = "发送失败,请打开二维码页面";
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = "发送失败,请打开二维码页面";
                }
                myHandler.sendMessage(msg);
            }
        }).start();

    }


    /**
     * Tv换源
     */
    private void changeTvFrom() {

        View view = LayoutInflater.from(mContext).inflate(R.layout.pop_tv_from, null, false);

        PopupWindow popupWindow = new PopupWindow(view, 400, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        popupWindow.setAnimationStyle(R.style.popRightAnim);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setTouchable(true);
        popupWindow.showAtLocation(frameLayout, Gravity.RIGHT, 0, 0);

        ListView list = view.findViewById(R.id.tv_list_view);
        TVChannelAdapter adapter = new TVChannelAdapter(mContext, fromList);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                playUrl = fromList.get(position).getSite();
                type = AppConst.TYPE_TV;
                playVideo();

                for (int i = 0; i < fromList.size(); i++) {
                    if (position == i) {
                        fromList.get(i).setIconId(1);
                    } else {
                        fromList.get(i).setIconId(0);
                    }
                }
                adapter.notifyDataSetChanged();
                popupWindow.dismiss();
            }
        });

        // 窗体背景半透明
        final WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.5f;
        getWindow().setAttributes(lp);

        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });

        int position = 0;
        for (int i = 0; i < fromList.size(); i++) {
            if (fromList.get(i).getIconId() == 1) {
                position = i;
            }
        }

        list.setSelection(position);
        list.smoothScrollToPosition(position);
    }


    /**
     * 打开二维码扫描
     */
    private final int REQUEST_CODE = 19999;
    private void requestCamera() {
        PermissionsUtil.requestPermission(getApplication(), new PermissionListener() {
            @Override
            public void permissionGranted(@NonNull String[] permissions) {
                Intent intent = new Intent(mContext, CaptureActivity.class);
                startActivityForResult(intent, REQUEST_CODE);
            }

            @Override
            public void permissionDenied(@NonNull String[] permissions) {
                toast(mContext, "扫码需要您授权访问摄像头");
            }
        }, Manifest.permission.CAMERA);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            //处理扫描结果(在界面上显示)
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                    String result = bundle.getString(CodeUtils.RESULT_STRING);
                    if (!result.startsWith("tvIp")) {
                        toast(mContext, "二维码不正确");
                    } else {
                        String ip = result.split("-")[1];
                        SharedPreferences sharedPreferences = getSharedPreferences("data", 0);
                        sharedPreferences.edit().putString("ip", ip).commit();
                        toast(mContext, "绑定成功");
                    }
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    toast(mContext, "解析二维码失败");
                }
            }
        }
    }

    public void toast(Context context, String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onPause() {
        super.onPause();
        videoView.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        videoView.resume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        videoView.release();

    }


    @Override
    public void onBackPressed() {
        if (!videoView.onBackPressed()) {
            super.onBackPressed();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        playUrl = intent.getStringExtra("url");
        type = intent.getStringExtra("type");

        playVideo();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_MENU:
                showChannelShade();
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                if (videoView.isPlaying()) {
                    videoView.pause();
                } else {
                    videoView.start();
                }
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                videoView.seekTo(videoView.getCurrentPosition() - 6000);
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                videoView.seekTo(videoView.getCurrentPosition() + 6000);
                break;

        }

        return super.onKeyDown(keyCode, event);
    }

    private final static int CODE_0 = 0;
    private final static int CODE_1 = 1;

    private class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CODE_0:
                    toast(mContext, msg.obj.toString());
                    break;
                //播放下载缓存文件
                case CODE_1:
                    playUrl = "file://" + getExternalCacheDir()+"/temp.mp4";
                    playVideo();
                    break;
            }
        }
    }
}