Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用遥控器来控制播放、暂停、快进、快退 #1302

Open
lingchen52 opened this issue Jul 18, 2018 · 20 comments
Open

用遥控器来控制播放、暂停、快进、快退 #1302

lingchen52 opened this issue Jul 18, 2018 · 20 comments

Comments

@lingchen52
Copy link

问题描述:

我在使用GSYVideoPlayer框架在盒子上播放视频时遇到一个问题:用遥控器没法控制播放(例如:播放、暂停、快进、快退),据我开发Android机顶盒的经验来看,主要原因在于播放器布局里的控件没处理焦点,我通过自定义播放器解决了用遥控器控制播放、暂停、快进、快退(快进快退时小窗口预览),但这种方式比较麻烦,使用上体验也不够好,代码也不优雅,可能会因为GSYVideoPlayer的更新而不得不更改,希望大神改一改GSYVideoPlayer,以便在Android盒子上用遥控器方便的控制播放。

public class VodVideoPlayer extends CustomGSYVideoPlayer {

    public VodVideoPlayer(Context context) {
        super(context);
    }

    public VodVideoPlayer(Context context, Boolean fullFlag) {
        super(context, fullFlag);
    }

    public VodVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
        getDisplay(context);
    }

    @Override
    public int getLayoutId() {
        return R.layout.video_layout_custom;
    }

    /**
     * 亮度、进度、音频
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int id = v.getId();
        float x = event.getX();
        float y = event.getY();
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
            return true;
        }
        if (id == R.id.fullscreen) {
            return false;
        }
        if (id == R.id.surface_container) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touchSurfaceDown(x, y);
                    break;
                case MotionEvent.ACTION_MOVE:
                    //触摸的X
//                    protected float mDownX;
                    //触摸的Y
//                    protected float mDownY;
                    float deltaX = x - mDownX;
                    float deltaY = y - mDownY;
                    float absDeltaX = Math.abs(deltaX);
                    float absDeltaY = Math.abs(deltaY);
                    if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                            || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
                        if (!mChangePosition && !mChangeVolume && !mBrightness) {
                            touchSurfaceMoveFullLogic(absDeltaX, absDeltaY);
                        }
                    }
                    touchSurfaceMove(deltaX, deltaY, y);
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
                        return true;
                    }
                    break;
            }
            gestureDetector.onTouchEvent(event);
        } else if (id == R.id.progress) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    cancelDismissControlViewTimer();
                case MotionEvent.ACTION_MOVE:
                    cancelProgressTimer();
                    ViewParent vpdown = getParent();
                    while (vpdown != null) {
                        vpdown.requestDisallowInterceptTouchEvent(true);
                        vpdown = vpdown.getParent();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    startProgressTimer();
                    ViewParent vpup = getParent();
                    while (vpup != null) {
                        vpup.requestDisallowInterceptTouchEvent(false);
                        vpup = vpup.getParent();
                    }
                    mBrightnessData = -1f;
                    break;
            }
        }
        return false;
    }

    //点击屏幕的默认值:屏幕中心点X,Y数值
    private static int pointX;
    private static int pointY;
    private static int moveX;
    private static int moveY;

    public static Point getDisplaySize(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    private static void getDisplay(Context context) {
        //获得屏幕宽高
        Point size = getDisplaySize(context);
        pointX = size.x / 2;
        pointY = size.y / 2;
        moveX = pointX;
        moveY = pointY;
    }

    //处理按键快进和快退
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.ACTION_DOWN:
                break;
            case KeyEvent.ACTION_UP:
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(LEFT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(RIGHT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                int state = getCurrentState();
                switch (state) {
                    case GSYVideoPlayer.CURRENT_STATE_PLAYING:
                        onVideoPause();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_PAUSE:
                        onVideoResume();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_AUTO_COMPLETE:
                        startPlayLogic();
                        isPlayComplete = false;
                        mSeekTimePosition = 0;
                        mProgressBar.setProgress(0);
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    private static boolean firstKeyDown = true;

    private void onClickUi() {
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
//                    return true;
        }
    }

    //第一次按下左右键
    private void firstKeyDown() {
        if (firstKeyDown) {
            touchSurfaceDown(pointX, pointY);
            firstKeyDown = false;
            if (mSeekTimePosition >= getDuration() || isPlayComplete) {

            } else {
                onStartTrackingTouch(mProgressBar);
            }
        }
    }

    public static boolean isPlayComplete = false;

    public static void setPlayComplete(boolean PlayComplete) {
        isPlayComplete = PlayComplete;
    }

    //连续按下左右键
    private void keyMove() {
        if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
            if (!mChangePosition && !mChangeVolume && !mBrightness) {
                touchSurfaceMoveFullLogic(Math.abs(moveX - pointX), 0);
            }
        }
        if (mSeekTimePosition >= getDuration() || isPlayComplete) {
            mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
            mBottomContainer.setVisibility(GONE);
        } else {
            touchSurfaceMove(moveX - pointX, 0, pointY);
            mBottomContainer.setVisibility(VISIBLE);
            onProgressChanged(mProgressBar, mSeekTimePosition * 100 / getDuration(), true);
        }
    }

    //定义变量
    private static final int LEFT = 0;
    private static final int RIGHT = 1;
    private static final int CANCLE = 2;

    private static int tim = 2;

    //程序启动时,初始化并发送消息
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LEFT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX - pointX / 13;
                        } else {
                            moveX = moveX - pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX - pointX / 200;
                    }
                    keyMove();
                    break;
                case RIGHT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX + pointX / 13;//13-20
                        } else {
                            moveX = moveX + pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX + pointX / 200;
                    }
                    keyMove();
                    break;
                case CANCLE:                        //停止按键
                    firstKeyDown = true;
                    moveX = pointX;
                    firstKeyDown = true;
                    tim = 2;
                    onStopTrackingTouch(mProgressBar);
                    mBottomContainer.setVisibility(GONE);
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
//                        return true;
                    }
                    break;
            }
        }
    };

    //重置
    public void resetTime() {
        mHandler.removeMessages(CANCLE);
        mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
    }

    @Override
    protected void dismissProgressDialog() {
        try {
            if (mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@lingchen52
Copy link
Author

另外望大神帮我看下上面的代码有啥需要优化的地方,不胜感激

@CarGuo
Copy link
Owner

CarGuo commented Jul 19, 2018

主要是个人没有设备调试,所以目前没有对电视进行适配,如果你调试了可以,可以在不影响项目原油逻辑的基础上,提交个pr

@lingchen52
Copy link
Author

@CarGuo 我调试过,没啥明显的问题,就是还需要优化优化,你可以用模拟器试一下,不用鼠标,只通过键盘的上下左右键和enter键来控制视频的播放、暂停、快进、快退(快进快退时小窗口预览)

@lingchen52
Copy link
Author

另外布局方面我没有更改,用的是CustomGSYVideoPlayer 自带的R.layout.video_layout_custom

@lingchen52
Copy link
Author

lingchen52 commented Jul 20, 2018

@CarGuo github pull半天老失败,我把文件的完整代码贴到这里,包路径:com.shuyu.gsyvideoplayer.video,你来提交

package com.shuyu.gsyvideoplayer.video;

import android.content.Context;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.WindowManager;

import com.shuyu.gsyvideoplayer.R;
import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer;



/**
 * 继承自CustomGSYVideoPlayer,主要用于Android盒子,实现了用遥控器控制
 * 播放、暂停、快进、快退(快进快退时小窗口预览)等功能。
 * Created by lingchen on 2017/9/25.
 * email:[email protected]
 */

public class TvVideoPlayer extends CustomGSYVideoPlayer {

    public TvVideoPlayer(Context context) {
        super(context);
    }

    public TvVideoPlayer(Context context, Boolean fullFlag) {
        super(context, fullFlag);
    }

    public TvVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
        getDisplay(context);
    }

    @Override
    public int getLayoutId() {
        return R.layout.video_layout_custom;
    }

    /**
     * 亮度、进度、音频
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int id = v.getId();
        float x = event.getX();
        float y = event.getY();
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
            return true;
        }
        if (id == R.id.fullscreen) {
            return false;
        }
        if (id == R.id.surface_container) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touchSurfaceDown(x, y);
                    break;
                case MotionEvent.ACTION_MOVE:
                    //触摸的X
//                    protected float mDownX;
                    //触摸的Y
//                    protected float mDownY;
                    float deltaX = x - mDownX;
                    float deltaY = y - mDownY;
                    float absDeltaX = Math.abs(deltaX);
                    float absDeltaY = Math.abs(deltaY);
                    if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                            || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
                        if (!mChangePosition && !mChangeVolume && !mBrightness) {
                            touchSurfaceMoveFullLogic(absDeltaX, absDeltaY);
                        }
                    }
                    touchSurfaceMove(deltaX, deltaY, y);
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
                        return true;
                    }
                    break;
            }
            gestureDetector.onTouchEvent(event);
        } else if (id == R.id.progress) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    cancelDismissControlViewTimer();
                case MotionEvent.ACTION_MOVE:
                    cancelProgressTimer();
                    ViewParent vpdown = getParent();
                    while (vpdown != null) {
                        vpdown.requestDisallowInterceptTouchEvent(true);
                        vpdown = vpdown.getParent();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    startProgressTimer();
                    ViewParent vpup = getParent();
                    while (vpup != null) {
                        vpup.requestDisallowInterceptTouchEvent(false);
                        vpup = vpup.getParent();
                    }
                    mBrightnessData = -1f;
                    break;
            }
        }
        return false;
    }

    //点击屏幕的默认值:屏幕中心点X,Y数值
    private static int pointX;
    private static int pointY;
    private static int moveX;
    private static int moveY;

    public static Point getDisplaySize(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    private static void getDisplay(Context context) {
        //获得屏幕宽高
        Point size = getDisplaySize(context);
        pointX = size.x / 2;
        pointY = size.y / 2;
        moveX = pointX;
        moveY = pointY;
    }

    //处理按键快进和快退
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.ACTION_DOWN:
                break;
            case KeyEvent.ACTION_UP:
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(LEFT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(RIGHT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                int state = getCurrentState();
                switch (state) {
                    case GSYVideoPlayer.CURRENT_STATE_PLAYING:
                        onVideoPause();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_PAUSE:
                        onVideoResume();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_AUTO_COMPLETE:
                        startPlayLogic();
                        isPlayComplete = false;
                        mSeekTimePosition = 0;
                        mProgressBar.setProgress(0);
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    private static boolean firstKeyDown = true;

    private void onClickUi() {
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
//                    return true;
        }
    }

    //第一次按下左右键
    private void firstKeyDown() {
        if (firstKeyDown) {
            touchSurfaceDown(pointX, pointY);
            firstKeyDown = false;
            if (mSeekTimePosition >= getDuration() || isPlayComplete) {

            } else {
                onStartTrackingTouch(mProgressBar);
            }
        }
    }

    public static boolean isPlayComplete = false;

    public static void setPlayComplete(boolean PlayComplete) {
        isPlayComplete = PlayComplete;
    }

    //连续按下左右键
    private void keyMove() {
        if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
            if (!mChangePosition && !mChangeVolume && !mBrightness) {
                touchSurfaceMoveFullLogic(Math.abs(moveX - pointX), 0);
            }
        }
        if (mSeekTimePosition >= getDuration() || isPlayComplete) {
            mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
            mBottomContainer.setVisibility(GONE);
        } else {
            touchSurfaceMove(moveX - pointX, 0, pointY);
            mBottomContainer.setVisibility(VISIBLE);
            onProgressChanged(mProgressBar, mSeekTimePosition * 100 / getDuration(), true);
        }
    }

    //定义变量
    private static final int LEFT = 0;
    private static final int RIGHT = 1;
    private static final int CANCLE = 2;

    private static int tim = 2;

    //程序启动时,初始化并发送消息
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LEFT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX - pointX / 13;
                        } else {
                            moveX = moveX - pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX - pointX / 200;
                    }
                    keyMove();
                    break;
                case RIGHT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX + pointX / 13;//13-20
                        } else {
                            moveX = moveX + pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX + pointX / 200;
                    }
                    keyMove();
                    break;
                case CANCLE:                        //停止按键
                    firstKeyDown = true;
                    moveX = pointX;
                    firstKeyDown = true;
                    tim = 2;
                    onStopTrackingTouch(mProgressBar);
                    mBottomContainer.setVisibility(GONE);
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
//                        return true;
                    }
                    break;
            }
        }
    };

    //重置
    public void resetTime() {
        mHandler.removeMessages(CANCLE);
        mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
    }

    @Override
    protected void dismissProgressDialog() {
        try {
            if (mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@kyriej
Copy link

kyriej commented Jul 24, 2018

没有机顶盒设备,推荐下用什么模拟器模拟呢

@lingchen52
Copy link
Author

网易mumu模拟器、逍遥模拟器、天天模拟器、夜神模拟器。。。。。。

@luomantic
Copy link

luomantic commented Oct 12, 2018

遥控器控制我改写了ListGSYVideoPlayer,然后做了播放,暂停,上一集,下一集。能正常使用。

@lingchen52
Copy link
Author

@luomantic 你怎么改写的ListGSYVideoPlayer,能把代码贴出来吗

@luomantic
Copy link

@luomantic 你怎么改写的ListGSYVideoPlayer,能把代码贴出来吗
额,这个仅仅只能做播放暂停,上一集,下一集啊。跟你要的可能不一样:
ListGSYVideoPlayer中增加:
`/**
* 播放下一集
*/
public boolean playNext() {
if (mPlayPosition < (mUriList.size() - 1)) {
mPlayPosition += 1;
GSYVideoModel gsyVideoModel = mUriList.get(mPlayPosition);
mSaveChangeViewTIme = 0;
setUp(mUriList, mCache, mPlayPosition, null, mMapHeadData, false);
if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
mTitleTextView.setText(gsyVideoModel.getTitle());
}
startPlayLogic();
return true;
}else if(mPlayPosition==(mUriList.size()-1)) {//循环播放
mPlayPosition=0;
GSYVideoModel gsyVideoModel = mUriList.get(mPlayPosition);
mSaveChangeViewTIme = 0;
setUp(mUriList, mCache, mPlayPosition, null, mMapHeadData, false);
if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
mTitleTextView.setText(gsyVideoModel.getTitle());
}
startPlayLogic();
return true;
}
return false;
}

/**
 *  播放上一集
 */
public void playPre() {
    if (mPlayPosition > 0) {
        mPlayPosition -= 1;
        GSYVideoModel gsyVideoModel = mUriList.get(mPlayPosition);
        mSaveChangeViewTIme = 0;
        setUp(mUriList, mCache, mPlayPosition, null, mMapHeadData, false);
        if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
            mTitleTextView.setText(gsyVideoModel.getTitle());
        }
        startPlayLogic();
    }else if(mPlayPosition==0) {//循环播放
        mPlayPosition = mUriList.size() -1 ;
        GSYVideoModel gsyVideoModel = mUriList.get(mPlayPosition);
        mSaveChangeViewTIme = 0;
        setUp(mUriList, mCache, mPlayPosition, null, mMapHeadData, false);
        if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
            mTitleTextView.setText(gsyVideoModel.getTitle());
        }
        startPlayLogic();
    }
}

/**
 * 暂停/播放
 */
public void pauseAndStart() {
    clickStartIcon();
}`

调用:
`public static int VIDEO_PLAY = 0;

Handler handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == VIDEO_PLAY) {
            detailPlayer.pauseAndStart();
        }
        return false;
    }
});

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    Message message = Message.obtain();
    if (keyCode == 23) {  // 相应的遥控器按键
        message.what = VIDEO_PLAY;
    }
    if (keyCode == 21) {
        ((ListDirectoryPlayer)detailPlayer.getCurrentPlayer()).playPre();
    }
    if (keyCode == 22) {
        ((ListDirectoryPlayer)detailPlayer.getCurrentPlayer()).playNext();
    }

    handler.sendMessage(message);
    return super.onKeyDown(keyCode, event);
}

`

@haohaozaici
Copy link
Contributor

好奇,遥控器的播放、暂停、快进、快退不能使用media session来实现吗?
可以使用exoplayer的官方demo在TV上试试

@renwfy
Copy link

renwfy commented Jul 23, 2019

你们TV都用什么播放器,这个版本太高了

@pengzhenol
Copy link

如果这个播放器底部Processbar(暂停时出现的,播放的时间轴) 和 ExoPlayer 默认的 Processbar 一个逻辑(Prosesbar 进度变化的时候,时间轴上显示的起始时间也跟着当前位置变化),基本就非常容易用遥控器实现seekTo的功能了,我用机顶盒测试了 ExoPlayer 的 DEMO 播放器,遥控器可以播放、暂停、快进、快退,但是 GSYplayer 里面就不行

@mSoftDeveloper
Copy link

支持大神开发一个tv版本的播放器,github上tv版本的播放器几乎没有

@cblsyp
Copy link

cblsyp commented Apr 16, 2020

为什么继承了StandardGSYVideoPlayer 重写了布局之后 在tv 通过遥控手动条用onClickUiToggle() 底部和顶部的UI控制层不显示。debug的时候父类的相关代码是执行了的 ,并且 mTopContainer, mBottomContainer;也不为空。

@lgj860123
Copy link

问题描述:

我在使用GSYVideoPlayer框架在盒子上播放视频时遇到一个问题:用遥控器没法控制播放(例如:播放、暂停、快进、快退),据我开发Android机顶盒的经验来看,主要原因在于播放器布局里的控件没处理焦点,我通过自定义播放器解决了用遥控器控制播放、暂停、快进、快退(快进快退时小窗口预览),但这种方式比较麻烦,使用上体验也不够好,代码也不优雅,可能会因为GSYVideoPlayer的更新而不得不更改,希望大神改一改GSYVideoPlayer,以便在Android盒子上用遥控器方便的控制播放。

public class VodVideoPlayer extends CustomGSYVideoPlayer {

    public VodVideoPlayer(Context context) {
        super(context);
    }

    public VodVideoPlayer(Context context, Boolean fullFlag) {
        super(context, fullFlag);
    }

    public VodVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
        getDisplay(context);
    }

    @Override
    public int getLayoutId() {
        return R.layout.video_layout_custom;
    }

    /**
     * 亮度、进度、音频
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int id = v.getId();
        float x = event.getX();
        float y = event.getY();
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
            return true;
        }
        if (id == R.id.fullscreen) {
            return false;
        }
        if (id == R.id.surface_container) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touchSurfaceDown(x, y);
                    break;
                case MotionEvent.ACTION_MOVE:
                    //触摸的X
//                    protected float mDownX;
                    //触摸的Y
//                    protected float mDownY;
                    float deltaX = x - mDownX;
                    float deltaY = y - mDownY;
                    float absDeltaX = Math.abs(deltaX);
                    float absDeltaY = Math.abs(deltaY);
                    if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                            || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
                        if (!mChangePosition && !mChangeVolume && !mBrightness) {
                            touchSurfaceMoveFullLogic(absDeltaX, absDeltaY);
                        }
                    }
                    touchSurfaceMove(deltaX, deltaY, y);
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
                        return true;
                    }
                    break;
            }
            gestureDetector.onTouchEvent(event);
        } else if (id == R.id.progress) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    cancelDismissControlViewTimer();
                case MotionEvent.ACTION_MOVE:
                    cancelProgressTimer();
                    ViewParent vpdown = getParent();
                    while (vpdown != null) {
                        vpdown.requestDisallowInterceptTouchEvent(true);
                        vpdown = vpdown.getParent();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    startDismissControlViewTimer();
                    startProgressTimer();
                    ViewParent vpup = getParent();
                    while (vpup != null) {
                        vpup.requestDisallowInterceptTouchEvent(false);
                        vpup = vpup.getParent();
                    }
                    mBrightnessData = -1f;
                    break;
            }
        }
        return false;
    }

    //点击屏幕的默认值:屏幕中心点X,Y数值
    private static int pointX;
    private static int pointY;
    private static int moveX;
    private static int moveY;

    public static Point getDisplaySize(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    private static void getDisplay(Context context) {
        //获得屏幕宽高
        Point size = getDisplaySize(context);
        pointX = size.x / 2;
        pointY = size.y / 2;
        moveX = pointX;
        moveY = pointY;
    }

    //处理按键快进和快退
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.ACTION_DOWN:
                break;
            case KeyEvent.ACTION_UP:
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(LEFT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                onClickUi();
                firstKeyDown();
                mHandler.sendEmptyMessage(RIGHT);
                mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
                resetTime();
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                int state = getCurrentState();
                switch (state) {
                    case GSYVideoPlayer.CURRENT_STATE_PLAYING:
                        onVideoPause();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_PAUSE:
                        onVideoResume();
                        break;
                    case GSYVideoPlayer.CURRENT_STATE_AUTO_COMPLETE:
                        startPlayLogic();
                        isPlayComplete = false;
                        mSeekTimePosition = 0;
                        mProgressBar.setProgress(0);
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    private static boolean firstKeyDown = true;

    private void onClickUi() {
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            onClickUiToggle();
            startDismissControlViewTimer();
//                    return true;
        }
    }

    //第一次按下左右键
    private void firstKeyDown() {
        if (firstKeyDown) {
            touchSurfaceDown(pointX, pointY);
            firstKeyDown = false;
            if (mSeekTimePosition >= getDuration() || isPlayComplete) {

            } else {
                onStartTrackingTouch(mProgressBar);
            }
        }
    }

    public static boolean isPlayComplete = false;

    public static void setPlayComplete(boolean PlayComplete) {
        isPlayComplete = PlayComplete;
    }

    //连续按下左右键
    private void keyMove() {
        if ((mIfCurrentIsFullscreen && mIsTouchWigetFull)
                || (mIsTouchWiget && !mIfCurrentIsFullscreen)) {
            if (!mChangePosition && !mChangeVolume && !mBrightness) {
                touchSurfaceMoveFullLogic(Math.abs(moveX - pointX), 0);
            }
        }
        if (mSeekTimePosition >= getDuration() || isPlayComplete) {
            mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
            mBottomContainer.setVisibility(GONE);
        } else {
            touchSurfaceMove(moveX - pointX, 0, pointY);
            mBottomContainer.setVisibility(VISIBLE);
            onProgressChanged(mProgressBar, mSeekTimePosition * 100 / getDuration(), true);
        }
    }

    //定义变量
    private static final int LEFT = 0;
    private static final int RIGHT = 1;
    private static final int CANCLE = 2;

    private static int tim = 2;

    //程序启动时,初始化并发送消息
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LEFT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX - pointX / 13;
                        } else {
                            moveX = moveX - pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX - pointX / 200;
                    }
                    keyMove();
                    break;
                case RIGHT:
                    if (tim > 0) {
                        if (tim > 1) {
                            moveX = moveX + pointX / 13;//13-20
                        } else {
                            moveX = moveX + pointX / 20;
                        }
                        tim -= 1;
                    } else {
                        moveX = moveX + pointX / 200;
                    }
                    keyMove();
                    break;
                case CANCLE:                        //停止按键
                    firstKeyDown = true;
                    moveX = pointX;
                    firstKeyDown = true;
                    tim = 2;
                    onStopTrackingTouch(mProgressBar);
                    mBottomContainer.setVisibility(GONE);
                    startDismissControlViewTimer();
                    touchSurfaceUp();
                    startProgressTimer();
                    //不要和隐藏虚拟按键后,滑出虚拟按键冲突
                    if (mHideKey && mShowVKey) {
//                        return true;
                    }
                    break;
            }
        }
    };

    //重置
    public void resetTime() {
        mHandler.removeMessages(CANCLE);
        mHandler.sendEmptyMessageDelayed(CANCLE, 2500);
    }

    @Override
    protected void dismissProgressDialog() {
        try {
            if (mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

大佬 你这个可以使用遥控器来控制快进 快退,暂停操作了嘛 ?可以发下源码给我看看嘛?

@wrz123456
Copy link

CustomGSYVideoPlayer 这个类改了么?

@CarGuo CarGuo unpinned this issue Jun 11, 2024
@wyfwrcode
Copy link

实测(TV机顶盒播放器)遥控器控制快进有问题,松开快进按钮时,当前进度是快进后的进
1725964844594
度,第二次进度就恢复到原先的进度

@wyfwrcode
Copy link

这里进行的是快进操作

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests