Open xingzhao-tt opened 8 years ago
延迟堆积这个问题看上去是ijkplayer在直播应用中的致命问题. 我现在尝试使用currentPlaybackTime和playableDuration来判断, 缓冲区数据是否已经堆积超过一定程度了, 如果是的话通过瞬间调快播放速度追赶一下进度. 不知是否可行.
@dourgulf
Hi Dourgulf,
Thanks for your comments. Could you help post more detail information, such as what file and what functions should I modify? It would be better if you could post your modification.
Thanks, Felix
我只是一个思路, 还在实践中, 有成果会第一时间分享. 目前来看playableDuration并不会比currentPlaybackTime快很多.
No such options, for now.
@bbcallen
Then what is the root cause of this issue? If we know the root cause, we might create a workaround.
Thanks, Felix
Reconnect could be a workaround.
在android我是这样做的,iOS就不太清楚了 //视频缓冲监听器 mVideoView.setOnBufferVideoListener(new VideoView.OnBufferVideoListener() { @Override public void bufferingStart() {
YLogUtil.logD2Tag(LOG_TAG_VIDEO, "bufferingStart");
startVideoSeekHandler();
}
@Override
public void bufferingEnd() {
YLogUtil.logD2Tag(LOG_TAG_VIDEO, "bufferingEnd");
removeVideoSeekHandler();
if (timeHandler != null)
timeHandler.removeMessages(VIDEO_SEEK_FAIL);
}
});
/* * 视频缓冲开始,加入handler,如果handler_VideoBuffer_DefaultTimeout秒后未缓冲完成,则执行视频跳帧 / public void startVideoSeekHandler() { timeHandler.removeMessages(VIDEO_SEEK); timeHandler.sendMessageDelayed(timeHandler.obtainMessage(VIDEO_SEEK), handler_VideoBuffer_DefaultTimeout); }
public void removeVideoSeekHandler() {
timeHandler.removeMessages(VIDEO_SEEK);
}
/**
* 开始跳帧
*/
public void onVideoSeek() {
YLogUtil.logD2Tag(LOG_TAG_VIDEO, "开始跳帧");
if (mVideoView != null) {
mVideoView.resume();
}
//发送视频跳帧失败handler
timeHandler.removeMessages(VIDEO_SEEK_FAIL);
timeHandler.sendMessageDelayed(timeHandler.obtainMessage(VIDEO_SEEK_FAIL),
handler_VideoSeek_Fail_DefaultTimeout);
}
@jyfree 你的播放延迟能做到几秒?
取决于handler_VideoBuffer_DefaultTimeout和handler_VideoSeek_Fail_DefaultTimeout的值,看你设置多大,值越小,延迟越小。但不能太小,自己可以调试一下,找到最合适的值
@jyfree 请问具体在哪个源文件的位置做修改?
在VideoView里,在监听器mInfoListener 设置一下
private OnInfoListener mInfoListener = new OnInfoListener() { @Override public boolean onInfo(IMediaPlayer mp, int what, int extra) { DebugLog.dfmt(TAG, "onInfo: (%d, %d)", what, extra); if (mOnInfoListener != null) { mOnInfoListener.onInfo(mp, what, extra); } else if (mMediaPlayer != null) { if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_START) { DebugLog.dfmt(TAG, "onInfo: (MEDIA_INFO_BUFFERING_START)");
YLogUtil.logD2Tag(TAG, "缓冲视频=========");
if (onBufferVideoListener != null)
onBufferVideoListener.bufferingStart();
//缓冲时显示load
// if (mMediaBufferingIndicator != null) // mMediaBufferingIndicator.setVisibility(View.VISIBLE); setBufferingMsg2Loading(); } else if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_END) { DebugLog.dfmt(TAG, "onInfo: (MEDIA_INFO_BUFFERING_END)"); YLogUtil.logD2Tag(TAG, "缓存完成============="); if (onBufferVideoListener != null) onBufferVideoListener.bufferingEnd(); //缓冲完成隐藏load if (mMediaBufferingIndicator != null) mMediaBufferingIndicator.setVisibility(View.GONE); } }
return true;
}
};
@jyfree 是调用哪个方法seek到最新帧的?参数是多少,就看到你sendMssege然后就没了~~
我这里没有做seek跳到那一帧,只是用了另外的一种办法,重新加载视频: public void resume() { if (mSurfaceHolder == null && mCurrentState == STATE_SUSPEND) { mTargetState = STATE_RESUME; } else if (mCurrentState == STATE_SUSPEND_UNSUPPORTED) { openVideo(); } }
ps:如果要用seek 的话,seek最新帧=跳帧前的位置+缓存所需要的时间
@jyfree 每次第一次播放的时候都是拉取到5s以前的帧,有办法拉取到服务器上最新的帧吗
没有,或许可以修改源码,利用双缓冲、甚至三缓冲机制,来缓存视频和音频数据。
这个查下你服务器
Hi Bilibili,
I am using this famous framework to play live stream on IOS. Now I have one problem while playing the stream. Could you help me? Thanks in advance.
I am playing stream with RTMP protocol. The delay is about 1 seconds at start time, but the delay increase to about 2 minutes after play 1 hour. Could you help give some information what options I should tune and how to debug it?
Thanks, Felix