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直播,在局域网环境,1080p、30fps的视频流。现在通过设置相关option参数,延时在300-350ms。怎么做进一步优化,达到100ms左右延时呢 #4267

Open
xufuji456 opened this issue May 21, 2018 · 57 comments

Comments

@xufuji456
Copy link

No description provided.

@xufuji456 xufuji456 changed the title 请问下做RTSP直播,在局域网环境,1080p、30fps的视频流。现在通过设置相关option参数,延时在300-350ms。 请问下做RTSP直播,在局域网环境,1080p、30fps的视频流。现在通过设置相关option参数,延时在300-350ms。怎么做进一步优化,达到100ms左右延时呢 May 21, 2018
@laval66
Copy link

laval66 commented May 24, 2018

首先能不能请问300-350ms是怎样设置参数的。。。

@xufuji456
Copy link
Author

xufuji456 commented May 24, 2018

probesize设置小点
infbuf设为1不限制输入缓存
fflags设为nobuffer
max_cached_duration设置小点
packet-buffering设为0
start-on-prepared设为1
备注:局域网环境测试

@haidejia319
Copy link

问下这个问题有解决吗,我也遇到这个问题

@xufuji456
Copy link
Author

做到了130ms,还得继续优化。。。

@haidejia319
Copy link

能看看你的option参数配置吗

@duhang324
Copy link

@xufuji456 请问怎么配置或者修改达到130ms?

@zhengchengbin610
Copy link

@xufuji456 朋友,你好,请问你的优化直播延时选项是否可以告知,我会有偿感谢的。

@xufuji456
Copy link
Author

  VideoOptionModel videoOptionMode01 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);//不额外优化
    VideoOptionModel videoOptionMode02 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200);//10240
    VideoOptionModel videoOptionMode03 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1);
    //pause output until enough packets have been read after stalling
    VideoOptionModel videoOptionMode04 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);//是否开启缓冲
    //drop frames when cpu is too slow:0-120
    VideoOptionModel videoOptionMode05 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);//丢帧,默认是1
    //automatically start playing on prepared
    VideoOptionModel videoOptionMode06 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1);
    VideoOptionModel videoOptionMode07 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);//默认值48
    //0:代表关闭;1:代表开启
    VideoOptionModel videoOptionMode08 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);//开启硬解
    VideoOptionModel videoOptionMode09 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0);//自动旋屏
    VideoOptionModel videoOptionMode10 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0);//处理分辨率变化
    //max buffer size should be pre-read:默认为15*1024*1024
    VideoOptionModel videoOptionMode11 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0);//最大缓存数
    VideoOptionModel videoOptionMode12 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);//默认最小帧数2
    VideoOptionModel videoOptionMode13 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30);//最大缓存时长
    //input buffer:don't limit the input buffer size (useful with realtime streams)
    VideoOptionModel videoOptionMode14 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);//是否限制输入缓存数
    VideoOptionModel videoOptionMode15 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer");

// VideoOptionModel videoOptionMode16 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");//tcp传输数据
VideoOptionModel videoOptionMode17 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100);//分析码流时长:默认1024*1000

备注:这是Android配置,ios参数类似

@xufuji456
Copy link
Author

@zhengchengbin610 感谢就不用了,大家相互学习而已

@zhengchengbin610
Copy link

@xufuji456 感谢的回复,max_cached_duration 这个选项是需要自己去按照网络文章加进去吧? 交个朋友,这是我的QQ:471102531

@xufuji456
Copy link
Author

max_cached_duration是自己加的,用来控制音视频缓存队列

@zhengchengbin610
Copy link

我试了你给我的配置选项,但是还是有480ms的延时,不知什么了,我是局域网播放rtsp 流,请问有什么建议吗?

@xufuji456
Copy link
Author

总延时=采集+编码(缓冲)+发送+传输+接收+解码(缓冲)+播放,你先确认下采集编码端有多少延时

@zhengchengbin610
Copy link

@xufuji456 明白,我确认一下,不过我测试的流没有音频,然后我disable 掉了音频流的播放

@zhengchengbin610
Copy link

@xufuji456 我用了一个其他的app 测试同一个流,延时在300ms左右,我的目标也就是300-350之间,但是我用ijkplayer的延时 一直保持在480ms 左右,感觉一直稳定在480ms,换了你的配置也是这样。对ijkplayer 还有什么修改优化的方法吗?

@xufuji456
Copy link
Author

你换成硬解码试下
//0:代表关闭;1:代表开启
VideoOptionModel videoOptionMode08 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);//开启硬解

@zhengchengbin610
Copy link

@xufuji456 是的,这个是否硬解码的选项 也有打开试过,基本没有什么变化,估计瓶颈延时不在解码部分,你是否可以给我修改的版本呢?

@Supecomer
Copy link

@zhengchengbin610 打开硬解后,可以降低 CPU 的使用率,可以让 CPU 做其他的事情,直播是因为码率一般不高,所以不明显,实际上是要好一些的

@zhengchengbin610
Copy link

@Supecomer 你说的了解,只是针对目前延时一直在480ms的问题上,用硬解码不太明显,当然CPU肯定低了,对于整个APP性能是有提升的,关于延时问题你有什么建议吗

@Somony
Copy link

Somony commented Sep 21, 2018

max_cached_duration是自己加的,用来控制音视频缓存队列

你好,我现在也是在局域网环境的推流,现在设置option后延迟在300ms左右,想进一步优化延迟,请问你添加max_cached_duration的逻辑能说下吗?非常感谢

@xufuji456
Copy link
Author

判断音视频缓存队列时间戳是否大于max_cached_duration,如果大于,就丢视频帧,要注意的是整个GOP都需要丢,否则会花屏

@xufuji456
Copy link
Author

你先把编译环境搭建好,建议在ubuntu环境编译。
具体修改可参考博客:https://www.jianshu.com/p/d6a5d8756eec

@Somony
Copy link

Somony commented Sep 26, 2018

你先把编译环境搭建好,建议在ubuntu环境编译。
具体修改可参考博客:https://www.jianshu.com/p/d6a5d8756eec

已经处理好了,谢谢

@Pingyong
Copy link

我设置上面的参数后,在局域网中还是有2秒的延迟呢?

@Pingyong
Copy link

max_cached_duration是自己加的,用来控制音视频缓存队列

你好,我现在也是在局域网环境的推流,现在设置option后延迟在300ms左右,想进一步优化延迟,请问你添加max_cached_duration的逻辑能说下吗?非常感谢

您好,我设置上面的参数后还是有2秒的延迟呢,我就用了一个无线路由器,么有接网线测试的

@xufuji456
Copy link
Author

1、你确认下推流端延时多少,用其他播放器拉流播放对比
2、确认下推流的码率、分辨率、帧率怎么样的

@zhengchengbin610
Copy link

@xufuji456 关于基于ijkplayer低延时300ms以内优化方法,是否可以交流,有偿的,感谢

@xufuji456
Copy link
Author

@zhengchengbin610 你那边直播的参数是怎么样的呢,分辨率、码率、帧率这些。
另外,这个300ms是在局域网测试的,外网环境具有不确定性

@cg19910712
Copy link

No description provided.

你好 ,怎么看log 确认是延迟300-500ms

@xufuji456
Copy link
Author

No description provided.

你好 ,怎么看log 确认是延迟300-500ms
@cg19910712 打开秒表,然后拍照对比推流端和拉流端的时差

@heimaxiaobo
Copy link

@xufuji456 大神你这个FFmpegAndroid里面的Onlive里面的so库 虽然能到达90ms 但是stop的时候没有发送teardown 来停止服务器发送rtsp

@QixinLi
Copy link

QixinLi commented May 11, 2019

你先把编译环境搭建好,建议在ubuntu环境编译。
具体修改可参考博客:https://www.jianshu.com/p/d6a5d8756eec

您好,请问您编译的so库可以分享一下吗?

@QixinLi
Copy link

QixinLi commented Jul 22, 2019 via email

@tommyfeng
Copy link

(Android平台) 请教下大家,网络波动的时候,或者RTSP服务器断开的时候,你们是如何捕捉到这个事件的?就是说没有一个错误回调的方法,我这边有设置 ijkMediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() { 但是没有作用,什么打印都没有。希望有大神指点下,谢谢!

@oaosj
Copy link

oaosj commented Nov 20, 2019

(Android平台) 请教下大家,网络波动的时候,或者RTSP服务器断开的时候,你们是如何捕捉到这个事件的?就是说没有一个错误回调的方法,我这边有设置 ijkMediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() { 但是没有作用,什么打印都没有。希望有大神指点下,谢谢!

和Android平台应该没关系,ffmpeg拉流,本质离不开av_read_frame,RTSP-Server断开或者网络出错,av_read_frame会返回错误码,用av_err2str可以查出具体原因。

@xufuji456
Copy link
Author

@xufuji456 大神你这个FFmpegAndroid里面的Onlive里面的so库 虽然能到达90ms 但是stop的时候没有发送teardown 来停止服务器发送rtsp

setup、teardown、play这些命令应该是推流端发送的,拉流端是接收命令进行处理

@xufuji456
Copy link
Author

你先把编译环境搭建好,建议在ubuntu环境编译。
具体修改可参考博客:https://www.jianshu.com/p/d6a5d8756eec

您好,请问您编译的so库可以分享一下吗?

在这里有 https://github.com/xufuji456/FFmpegAndroid

@tommyfeng
Copy link

@xufuji456 大神你这个FFmpegAndroid里面的Onlive里面的so库 虽然能到达90ms 但是stop的时候没有发送teardown 来停止服务器发送rtsp

setup、teardown、play这些命令应该是推流端发送的,拉流端是接收命令进行处理

退出拉流的时候,确实应该要发送 teardown 吧。 我用vlc拉rtsp然后退出的时候,vlc 是有发送 teardwon指令给到服务器端的,但是用这个就没有发送teardwon 指令

@tommyfeng
Copy link

(Android平台) 请教下大家,网络波动的时候,或者RTSP服务器断开的时候,你们是如何捕捉到这个事件的?就是说没有一个错误回调的方法,我这边有设置 ijkMediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() { 但是没有作用,什么打印都没有。希望有大神指点下,谢谢!

和Android平台应该没关系,ffmpeg拉流,本质离不开av_read_frame,RTSP-Server断开或者网络出错,av_read_frame会返回错误码,用av_err2str可以查出具体原因。

ijkplayer 有接口可以直接操作 av_read_frame 吗? av_err2str 这个在哪里可以查呢?

@oaosj
Copy link

oaosj commented Nov 21, 2019

(Android平台) 请教下大家,网络波动的时候,或者RTSP服务器断开的时候,你们是如何捕捉到这个事件的?就是说没有一个错误回调的方法,我这边有设置 ijkMediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() { 但是没有作用,什么打印都没有。希望有大神指点下,谢谢!

和Android平台应该没关系,ffmpeg拉流,本质离不开av_read_frame,RTSP-Server断开或者网络出错,av_read_frame会返回错误码,用av_err2str可以查出具体原因。

ijkplayer 有接口可以直接操作 av_read_frame 吗? av_err2str 这个在哪里可以查呢?

没直接操作av_read_frame的,这个在ff_ffplay.c读线程里面。
如果is->eof,在ffp_toggle_buffering是有实现通知的ffp_notify_msg2。
如果网络出错,也有匹配好几个错误码,下面的if(pb_error){..}
然后线程就被挂起等待,再次唤醒进入continue,回到循环开头,可能有加了暂停、abort之类的标志,然后退出循环了。
看了下,EOF好像返回的是BUFFERRING_END之类的标志,可能是在状态的监听里面。pb_error应该才回调到你说的OnErrorListener。这部分没仔细看。你可以在av_read_frame返回小于0的条件下加个
av_log(ffp, AV_LOG_ERROR, "av_read_frame error: %s\n", av_err2str(ret)); 重新编译看看在你的环境下,网络出错,断服务器返回什么错误,就比较容易追溯到回调的位置。

`
ret = av_read_frame(ic, pkt);
if (ret < 0) {
int pb_eof = 0;
int pb_error = 0;
if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
ffp_check_buffering_l(ffp);
pb_eof = 1;
// check error later
}
if (ic->pb && ic->pb->error) {
pb_eof = 1;
pb_error = ic->pb->error;
}
if (ret == AVERROR_EXIT) {
pb_eof = 1;
pb_error = AVERROR_EXIT;
}

        if (pb_eof) {
            if (is->video_stream >= 0)
                packet_queue_put_nullpacket(&is->videoq, is->video_stream);
            if (is->audio_stream >= 0)
                packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
            if (is->subtitle_stream >= 0)
                packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
            is->eof = 1;
        }
        if (pb_error) {
            if (is->video_stream >= 0)
                packet_queue_put_nullpacket(&is->videoq, is->video_stream);
            if (is->audio_stream >= 0)
                packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
            if (is->subtitle_stream >= 0)
                packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
            is->eof = 1;
            ffp->error = pb_error;
            av_log(ffp, AV_LOG_ERROR, "av_read_frame error: %s\n", ffp_get_error_string(ffp->error));
            // break;
        } else {
            ffp->error = 0;
        }
        if (is->eof) {
            ffp_toggle_buffering(ffp, 0);
            SDL_Delay(100);
        }
        SDL_LockMutex(wait_mutex);
        SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
        SDL_UnlockMutex(wait_mutex);
        ffp_statistic_l(ffp);
        continue;
    } else {
        is->eof = 0;
    }

`

@tommyfeng
Copy link

(Android平台) 请教下大家,网络波动的时候,或者RTSP服务器断开的时候,你们是如何捕捉到这个事件的?就是说没有一个错误回调的方法,我这边有设置 ijkMediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() { 但是没有作用,什么打印都没有。希望有大神指点下,谢谢!

和Android平台应该没关系,ffmpeg拉流,本质离不开av_read_frame,RTSP-Server断开或者网络出错,av_read_frame会返回错误码,用av_err2str可以查出具体原因。

ijkplayer 有接口可以直接操作 av_read_frame 吗? av_err2str 这个在哪里可以查呢?

没直接操作av_read_frame的,这个在ff_ffplay.c读线程里面。
如果is->eof,在ffp_toggle_buffering是有实现通知的ffp_notify_msg2。
如果网络出错,也有匹配好几个错误码,下面的if(pb_error){..}
然后线程就被挂起等待,再次唤醒进入continue,回到循环开头,可能有加了暂停、abort之类的标志,然后退出循环了。
看了下,EOF好像返回的是BUFFERRING_END之类的标志,可能是在状态的监听里面。pb_error应该才回调到你说的OnErrorListener。这部分没仔细看。你可以在av_read_frame返回小于0的条件下加个
av_log(ffp, AV_LOG_ERROR, "av_read_frame error: %s\n", av_err2str(ret)); 重新编译看看在你的环境下,网络出错,断服务器返回什么错误,就比较容易追溯到回调的位置。

`
ret = av_read_frame(ic, pkt);
if (ret < 0) {
int pb_eof = 0;
int pb_error = 0;
if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
ffp_check_buffering_l(ffp);
pb_eof = 1;
// check error later
}
if (ic->pb && ic->pb->error) {
pb_eof = 1;
pb_error = ic->pb->error;
}
if (ret == AVERROR_EXIT) {
pb_eof = 1;
pb_error = AVERROR_EXIT;
}

        if (pb_eof) {
            if (is->video_stream >= 0)
                packet_queue_put_nullpacket(&is->videoq, is->video_stream);
            if (is->audio_stream >= 0)
                packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
            if (is->subtitle_stream >= 0)
                packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
            is->eof = 1;
        }
        if (pb_error) {
            if (is->video_stream >= 0)
                packet_queue_put_nullpacket(&is->videoq, is->video_stream);
            if (is->audio_stream >= 0)
                packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
            if (is->subtitle_stream >= 0)
                packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
            is->eof = 1;
            ffp->error = pb_error;
            av_log(ffp, AV_LOG_ERROR, "av_read_frame error: %s\n", ffp_get_error_string(ffp->error));
            // break;
        } else {
            ffp->error = 0;
        }
        if (is->eof) {
            ffp_toggle_buffering(ffp, 0);
            SDL_Delay(100);
        }
        SDL_LockMutex(wait_mutex);
        SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
        SDL_UnlockMutex(wait_mutex);
        ffp_statistic_l(ffp);
        continue;
    } else {
        is->eof = 0;
    }

`

嗯,按照你说的加了打印,断开服务器之后,返回的错误是 end of file
image
这个是对应 ijkplayer 的哪个回调呢?

@Glumelin
Copy link

做到了130ms,还得继续优化。。。

做到了130ms,还得继续优化。。。

@xufuji456 能告知做到130ms的option的设置参数吗?

@zsinba
Copy link

zsinba commented Apr 10, 2020

我在html5,最低做到了270ms。
就再下不去了。
楼请的130,是ijkplayer,不是H5的。
到130估计也很难下了。

我尝试使用rtsp局域网,最低到80ms。
但是些都不好在HTMl5上面使用。

@zsinba
Copy link

zsinba commented Apr 10, 2020

最大时延是在: 播放器端; 流到了后要解码。这是软解的可能至少要50ms的时延了。

@mafanwei
Copy link

乐播投屏可以在1080p做到wifi 40ms延时,他们是如何实现的呢?(局域网)

@zsinba
Copy link

zsinba commented Apr 13, 2020

乐播投屏可以在1080p做到wifi 40ms延时,他们是如何实现的呢?(局域网)

猜测并不是1080P,只是分辨率达到了1920*1080. 1080P是逐行扫描,直播或者低延时的高清,可能都比较困难。
码率不足,造成显示上面打折。
还有,你的40ms是如何测试的?RTSP Lan网络测试最快测到80ms。

如果 知道乐投是1080P,麻烦告知。

@mafanwei
Copy link

乐播投屏可以在1080p做到wifi 40ms延时,他们是如何实现的呢?(局域网)

猜测并不是1080P,只是分辨率达到了1920*1080. 1080P是逐行扫描,直播或者低延时的高清,可能都比较困难。
码率不足,造成显示上面打折。
还有,你的40ms是如何测试的?RTSP Lan网络测试最快测到80ms。

如果 知道乐投是1080P,麻烦告知。

分辨率确实是1920x1080,延时利用的秒表,让投屏端显示秒表。然后把接收端和投屏端放在一起,用另一个设备拍照。上面显示的差值即为延迟。乐播投屏和接收端都可以在网上下到,很容易验证。
我现在想做一个基于rtsp的投屏,查了查目前的github,能跑通的就是libstreaming,但他是投的照相机,苦于codec不是很熟,不知道从何改起,把数据源变成屏幕

@xufuji456
Copy link
Author

目前市面上产品以80ms延时为主,偶尔出现40ms,局域网传输,不考虑网络抖动和网络延时。
采用h265编解码,提高压缩率,降低传输延时,自定义传输层协议。

@tianxiaofan
Copy link

tianxiaofan commented Sep 28, 2020

@xufuji456 请问怎么配置或者修改达到130ms?

如果不嫌多个库的话,可以使用live555 来连接rtsp流,,,github上可以找到一个live55helper,是把live555进行一次封装,很好用..使用liv555出来的数据直接就是h265或者265的裸流,给ffmpeg直接解码就行..这样在我的环境下(摄像头->H3516a编码->live555->ffmpeg软解->opengl渲染)效率解码综合下来能有180ms..我打印过日志从live555出来的数据到软解完4-6ms,主要延迟还是在摄像头编码板.pc端的,仅供参考

@Glumelin
Copy link

No description provided.

想咨询下
局域网环境下,做rtsp直播,播放一段时间后,画面就卡住不动,但是其它都显示正常的

@xufuji456
Copy link
Author

你看下是不是网络抖动引用卡顿的

@Glumelin
Copy link

Glumelin commented Jan 21, 2021 via email

@wuhongsheng
Copy link

  VideoOptionModel videoOptionMode01 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);//不额外优化
    VideoOptionModel videoOptionMode02 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200);//10240
    VideoOptionModel videoOptionMode03 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1);
    //pause output until enough packets have been read after stalling
    VideoOptionModel videoOptionMode04 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);//是否开启缓冲
    //drop frames when cpu is too slow:0-120
    VideoOptionModel videoOptionMode05 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);//丢帧,默认是1
    //automatically start playing on prepared
    VideoOptionModel videoOptionMode06 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1);
    VideoOptionModel videoOptionMode07 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);//默认值48
    //0:代表关闭;1:代表开启
    VideoOptionModel videoOptionMode08 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);//开启硬解
    VideoOptionModel videoOptionMode09 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0);//自动旋屏
    VideoOptionModel videoOptionMode10 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0);//处理分辨率变化
    //max buffer size should be pre-read:默认为15*1024*1024
    VideoOptionModel videoOptionMode11 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0);//最大缓存数
    VideoOptionModel videoOptionMode12 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);//默认最小帧数2
    VideoOptionModel videoOptionMode13 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30);//最大缓存时长
    //input buffer:don't limit the input buffer size (useful with realtime streams)
    VideoOptionModel videoOptionMode14 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);//是否限制输入缓存数
    VideoOptionModel videoOptionMode15 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer");

// VideoOptionModel videoOptionMode16 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");//tcp传输数据
VideoOptionModel videoOptionMode17 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100);//分析码流时长:默认1024*1000

备注:这是Android配置,ios参数类似
使用tcp传输会增加延时,不实用会花屏,请问有什么优化方法吗

@ProFive
Copy link

ProFive commented Mar 5, 2021

Dear @wuhongsheng ,

  1. I try on android then it's work but take more time for video rendering started ( About 4-10 seconds)
  2. Run on iOS then it was black color live streaming

flutter: timeline view = 93.0
flutter: [inf] 2021-03-05 15:12:35.507872 [fijk] create player id:21
flutter: [err] 2021-03-05 15:12:35.508084 [fijk] FijkPlayer{id:21} prepareAsync invalid state:FijkState.idle
flutter: [inf] 2021-03-05 15:12:35.508135 [fijk] FijkPlayer{id:21} invoke setVolume 1.0
flutter: [inf] 2021-03-05 15:12:35.508194 [fijk] FijkPlayer{id:21} invoke setVolume 1.0
flutter: [inf] 2021-03-05 15:12:35.508251 [fijk] FijkPlayer{id:21} setOption k:request-screen-on, v:1
flutter: [inf] 2021-03-05 15:12:35.512291 [fijk] FijkPlayer{id:21} setOption k:request-audio-focus, v:1
flutter: [inf] 2021-03-05 15:12:35.516674 [fijk] FijkPlayer{id:21} setOption k:enable-snapshot, v:1
flutter: {log} {DeviceListWidgetModel} {onViewDetailDevice} {LogLevel.INFO} {05 March 2021 03:12:35 PM}
flutter: [inf] 2021-03-05 15:12:35.517623 [fijk] FijkPlayer{id:21} setOption k:rtsp_transport, v:tcp
flutter: [inf] 2021-03-05 15:12:35.518050 [fijk] FijkPlayer{id:21} setOption k:start-on-prepared, v:1
flutter: [inf] 2021-03-05 15:12:35.518230 [fijk] FijkPlayer{id:21} setOption k:mediacodec-all-videos, v:1
flutter: [inf] 2021-03-05 15:12:35.518404 [fijk] FijkPlayer{id:21} setOption k:probesize, v:200
flutter: [inf] 2021-03-05 15:12:35.518638 [fijk] FijkPlayer{id:21} setOption k:analyzemaxduration, v:1000
flutter: [inf] 2021-03-05 15:12:35.518894 [fijk] FijkPlayer{id:21} setOption k:flush_packets, v:1
flutter: [inf] 2021-03-05 15:12:35.519150 [fijk] FijkPlayer{id:21} setOption k:fast, v:1
flutter: [inf] 2021-03-05 15:12:35.519369 [fijk] FijkPlayer{id:21} setOption k:packet-buffering, v:0
flutter: [inf] 2021-03-05 15:12:35.519547 [fijk] FijkPlayer{id:21} setOption k:mediacodec-auto-rotate, v:0
flutter: [inf] 2021-03-05 15:12:35.519808 [fijk] FijkPlayer{id:21} setOption k:mediacodec-handle-resolution-change, v:0
flutter: [inf] 2021-03-05 15:12:35.519990 [fijk] FijkPlayer{id:21} setOption k:max-buffer-size, v:0
flutter: [inf] 2021-03-05 15:12:35.520308 [fijk] FijkPlayer{id:21} setOption k:min-frames, v:2
flutter: [inf] 2021-03-05 15:12:35.520509 [fijk] FijkPlayer{id:21} setOption k:max_cached_duration, v:30
flutter: [inf] 2021-03-05 15:12:35.520797 [fijk] FijkPlayer{id:21} setOption k:infbuf, v:1
flutter: [inf] 2021-03-05 15:12:35.542888 [fijk] FijkPlayer{id:21} setOption k:fflags, v:nobuffer
flutter: [inf] 2021-03-05 15:12:35.545738 [fijk] FijkPlayer{id:21} setOption k:skip_loop_filter, v:48
flutter: [inf] 2021-03-05 15:12:35.546292 [fijk] FijkPlayer{id:21} setOption k:framedrop, v:1
flutter: [inf] 2021-03-05 15:12:35.546631 [fijk] FijkPlayer{id:21} invoke setDataSource rtsp:https://user:[email protected]:10360/xxxxx
flutter: [inf] 2021-03-05 15:12:35.547171 [fijk] FijkPlayer{id:21} state changed to FijkState.initialized <= FijkState.idle
flutter: [inf] 2021-03-05 15:12:35.547526 [fijk] FijkPlayer{id:21} invoke prepareAsync and start #1
flutter: [inf] 2021-03-05 15:12:35.547570 [fijk] FijkPlayer{id:21} setOption k:start-on-prepared, v:1
flutter: [inf] 2021-03-05 15:12:35.549458 [fijk] FijkPlayer{id:21} state changed to FijkState.asyncPreparing <= FijkState.initialized
flutter: [inf] 2021-03-05 15:12:35.549763 [fijk] FijkPlayer{id:21} invoke prepareAsync and start #1 -> done
flutter: [inf] 2021-03-05 15:12:35.549862 [fijk] FijkPlayer{id:21} state changed to FijkState.initialized <= FijkState.idle
flutter: [inf] 2021-03-05 15:12:35.550192 [fijk] FijkPlayer{id:21} state changed to FijkState.asyncPreparing <= FijkState.initialized
flutter: [inf] 2021-03-05 15:12:35.791240 [fijk] FijkPlayer{id:21} audio rendering started
flutter: [inf] 2021-03-05 15:12:35.792425 [fijk] FijkPlayer{id:21} prepared duration 0:00:00.000000
flutter: [inf] 2021-03-05 15:12:35.792573 [fijk] FijkPlayer{id:21} setupSurface
flutter: [inf] 2021-03-05 15:12:35.793095 [fijk] FijkPlayer{id:21} rotate degree 0
flutter: [inf] 2021-03-05 15:12:35.793193 [fijk] FijkPlayer{id:21} state changed to FijkState.prepared <= FijkState.asyncPreparing
flutter: [inf] 2021-03-05 15:12:35.794240 [fijk] FijkPlayer{id:21} setupSurface
flutter: [inf] 2021-03-05 15:12:35.794449 [fijk] FijkPlayer{id:21} state changed to FijkState.started <= FijkState.prepared
flutter: [inf] 2021-03-05 15:12:35.794826 [fijk] FijkPlayer{id:21} setupSurface
flutter: [inf] 2021-03-05 15:12:35.795131 [fijk] view setup, vid:19
flutter: [inf] 2021-03-05 15:12:35.795500 [fijk] view setup, vid:19
flutter: [inf] 2021-03-05 15:12:35.796749 [fijk] view setup, vid:19
flutter: [inf] 2021-03-05 15:12:40.258153 [fijk] FijkPlayer{id:21} size changed (1920.0, 1080.0)
flutter: [inf] 2021-03-05 15:12:40.262189 [fijk] FijkPlayer{id:21} video rendering started
flutter: [inf] 2021-03-05 15:12:40.400469 [fijk] FijkPlayer{id:21} size changed (1920.0, 1080.0)
flutter: [inf] 2021-03-05 15:12:40.650321 [fijk] FijkPlayer{id:21} size changed (1920.0, 1080.0)

@zhwork92d
Copy link

这个能到ubuntu(非安卓)上使用吗?

@chenanghui
Copy link

H265的1080P的实时流,硬解码,拉一个流没问题,如果同时拉两个流,在iOS端会有卡顿,知道可能的原因是什么吗?安卓端是没问题

@JcTom
Copy link

JcTom commented Aug 5, 2024

h265的情况下1080根据网络上修改确实是在100左右(80-130),但是也看设备端,手机是推流是能轻松达到

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