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

rtsp弱网或断流情况下监听不到任何状态 #2757

Closed
LXLYHM opened this issue Jun 5, 2020 · 8 comments
Closed

rtsp弱网或断流情况下监听不到任何状态 #2757

LXLYHM opened this issue Jun 5, 2020 · 8 comments

Comments

@LXLYHM
Copy link

LXLYHM commented Jun 5, 2020

(!!!!请务必务必按照issue模板,修改 后提交问题!!!!,不按模板提Isuue删除处理)

(ps 首页问题集锦和demo请先了解一下!)

提问前建议先看看: https://mp.weixin.qq.com/s/HjSdmAsHuvixCH_EWdvk3Q

问题描述:

您好,目前我使用#2112 下载的so库播放rtsp视频流,但是想做弱网或断流等卡住监听失败,收不到任何监听信息,就是画面一直卡住了。
播放链接:rtsp://27.158.58.94:26902/0_0
引用代码如下,求告知有没有啥办法能解决?比如监听到缓冲中和缓冲完成或暂停状态
谢谢大佬帮忙~

问题机型/系统:所有安卓手机

GSY依赖版本

implementation 'com.shuyu:gsyVideoPlayer-java:6.0.1'
implementation 'com.shuyu:GSYVideoPlayer-exo2:6.0.1'
implementation 'com.shuyu:gsyVideoPlayer-ex_so:6.0.1'

implementation 'com.shuyu:gsyVideoPlayer-java:7.1.4'

Demo中的复现步骤

Demo中的detailPlayer页面打开后XXXX会出现这个问题。

问题代码:
初始化

val list = ArrayList<VideoOptionModel>()
        var videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp")
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_flags", "prefer_tcp")
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "allowed_media_types", "video") //根据媒体类型来配置
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 2000)//20000
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "buffer_size", 1316)
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 1)  // 无限读
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100)
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 10240)
        list.add(videoOptionModel)
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1)
        list.add(videoOptionModel)
         //重定向问题 ,切换同一网段下不同端口视频源不变,需要引用附加so库
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", -1)
        list.add(videoOptionModel)
        val videoOptionModel2 = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", -1)
        list.add(videoOptionModel2)
        val videoOptionModel3 = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp")
        list.add(videoOptionModel3)
        //  关闭播放器缓冲,这个必须关闭,否则会出现播放一段时间后,一直卡主,控制台打印 FFP_MSG_BUFFERING_START
        videoOptionModel = VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0)
        list.add(videoOptionModel)
        GSYVideoManager.instance().optionModelList = list
        videoPlayer.setUp(playerUrl, false, "")
        videoPlayer.titleTextView.visibility = View.GONE
        videoPlayer.backButton.visibility = View.GONE//返回按钮
        videoPlayer.fullscreenButton.visibility = View.GONE//全屏按钮
        videoPlayer.isNeedShowWifiTip = false//是否需要4G网络提醒

        videoPlayer.startPlayLogic()

自定义继承重写

/**
 * 重写视频播放器 隐藏进度条等UI布局
 */
public class KTStandardGSYVideoPlayer extends StandardGSYVideoPlayer {
    public KTStandardGSYVideoPlayer(Context context, Boolean fullFlag) {
        super(context, fullFlag);
    }
    public KTStandardGSYVideoPlayer(Context context) { super(context);}
    public KTStandardGSYVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override public int getLayoutId() {
        return R.layout.video_layout_cover;
    }

    /**
     * 隐藏所有UI透明
     */
    @Override protected void init(Context context) {
        super.init(context);
        setAlphaTo0f(mLockScreen,mBottomContainer,mBottomProgressBar);
    }
    protected void  setAlphaTo0f(View... vs){
        for (View view : vs) { view.setAlpha(0.0f); }
    }

    /**
     * 去掉双击暂停事件
     */
    @Override protected void touchDoubleUp() {
//        super.touchDoubleUp();
    }

    /******************* 下方重载方法,在播放开始不显示底部进度和按键,不需要可屏蔽 ********************/
    @Override protected void onClickUiToggle() {
        if (mIfCurrentIsFullscreen && mLockCurScreen && mNeedLockFull) {
            setViewShowState(mLockScreen, VISIBLE);
            return;
        }
        super.onClickUiToggle();
    }
    @Override protected void changeUiToNormal() {
        super.changeUiToNormal();
    }
    @Override protected void changeUiToPreparingShow() {
        super.changeUiToPreparingShow();
        Debuger.printfLog("Sample changeUiToPreparingShow");
        setViewShowState(mBottomContainer, INVISIBLE);
        setViewShowState(mStartButton, INVISIBLE);
    }
    @Override protected void changeUiToPlayingBufferingShow() {
        super.changeUiToPlayingBufferingShow();
        Debuger.printfLog("Sample changeUiToPlayingBufferingShow");
        setViewShowState(mBottomContainer, INVISIBLE);
        setViewShowState(mStartButton, INVISIBLE);
    }
    @Override protected void changeUiToPlayingShow() {
        super.changeUiToPlayingShow();
        Debuger.printfLog("Sample changeUiToPlayingShow");
        setViewShowState(mBottomContainer, INVISIBLE);
        setViewShowState(mStartButton, INVISIBLE);
    }
    @Override public void startAfterPrepared() {
        super.startAfterPrepared();
        Debuger.printfLog("Sample startAfterPrepared");
        setViewShowState(mBottomContainer, INVISIBLE);
        setViewShowState(mStartButton, INVISIBLE);
        setViewShowState(mBottomProgressBar, GONE);
    }

    //状态监听
    private VideoStateListener mVideoStateListener = null;
    public void setVideoStateListener(VideoStateListener mVideoStateListener){
        this.mVideoStateListener = mVideoStateListener;
    }
    public interface VideoStateListener{
        void getVideoStateListener(int state);
    }
    @Override
    protected void setStateAndUi(int state) {
        super.setStateAndUi(state);
        LogUtils.e("状态监听setStateAndUi:" + state);
        if (mVideoStateListener != null) mVideoStateListener.getVideoStateListener(state);
    }

    @Override
    public void onError(int what, int extra) {
        LogUtils.e("onError错误:" + what);
        super.onError(what, extra);

    }
}

问题log(如果有)


xxxxxxx

@dream5788
Copy link

同样问题,怎么解决啊?

@CarGuo
Copy link
Owner

CarGuo commented Jun 5, 2020

继承后看看 onError 或者 onInfo 的回调

@LXLYHM
Copy link
Author

LXLYHM commented Jun 5, 2020

已经继承了 onError 或onInfo没回调日志

@CarGuo
Copy link
Owner

CarGuo commented Jun 5, 2020

如果出现 loading buffer 是会走 onInfo 的,如果是正常流只是画面卡住,那就没办法回调了,自己加个定时器,然后再用 onSurfaceUpdated 里判断下是否出现过更新。

因为 ijk 用的 ffmepg 没有往上把状态上发上来。

ps onSurfaceUpdated 只支持默认的 GSYTextureView 模式。

@LXLYHM
Copy link
Author

LXLYHM commented Jun 5, 2020

没出现 loading buffer,是正常流忽然断了或者弱网卡住了,收不到回调。但是ios那边同样情况用ijk能灵敏监听到停止状态4,所以就想说问问安卓这边有没有办法监听到。

@CarGuo
Copy link
Owner

CarGuo commented Jun 5, 2020

没有,我这么测试的很好,没看到有往上抛的信息

@LXLYHM
Copy link
Author

LXLYHM commented Jun 8, 2020

最后写了定时器监听surfaceUpdataed解决了当前需求,谢谢作者大佬给的方案

private long updateTimer = 0;
    private boolean isStop;
    @Override
    public void onSurfaceUpdated(Surface surface) {
        super.onSurfaceUpdated(surface);
        if (isStop){
            isStop = false;
            if (mVideoStateListener != null) mVideoStateListener.onSurfaceUpdatedStop(false);
        }
        updateTimer = 0;
        mHandler.removeMessages(1);
        mHandler.sendEmptyMessageDelayed(1,1000);
    }
    private Handler mHandler = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            updateTimer++;
            mHandler.sendEmptyMessageDelayed(1,1000);
            if(updateTimer >= 3){
                isStop = true;
                mHandler.removeMessages(1);
                if (mVideoStateListener != null) mVideoStateListener.onSurfaceUpdatedStop(true);
            }
        }
    };

有更好办法求分享

@CarGuo
Copy link
Owner

CarGuo commented Jun 8, 2020

最好的办法肯定还是从 ffmpeg 层面去上抛,这个需要你修改 ijk 的 ffplay 来做兼容~

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

3 participants