我正在使用由AppUnite构建的FFMPEG和最新的stagefright支持补丁来播放http直播流:https://review.appunite.com/#/c/1779/
由于流未从0开始,我添加了以下代码以避免出现黑屏:
struct Player {
+ int64_t video_start_time;
}
void player_get_video_duration(struct Player *player) {
+ player->video_start_time = 0;
+ for (i = 0; i < player->capture_streams_no; ++i) {
+ AVStream *stream = player->input_streams[i];
+ if (stream->start_time > 0) {
+ player->video_start_time = av_rescale_q(
+ stream->start_time, stream->time_base, AV_TIME_BASE_Q);
+
+ LOGI(3, "player_set_data_source stream[%d] start_time: %ld",
+ i, player->video_start_time);
+
+ break;
+ }
+ }
}
enum WaitFuncRet player_wait_for_frame(
struct Player *player, double time, int stream_no) {
- int64_t current_time = av_gettime();
+ int64_t current_time = av_gettime() + player->video_start_time;
}
但是,只要player_wait_for_frame中的sleep_time低于0,播放就会冻结,然后挂起等待永不到来的帧。由player_alloc_queues函数分配的队列似乎不够大,无法容纳在player_open_input和player_start_decoding_threads之间推送的实时流。但是,增加队列中的节点数并不能解决问题。问题似乎在player_wait_for_frame方法中很明显,但我无法找到解决方案。
我花了很多时间试图解决这个令人讨厌的问题,但到目前为止还没有成功。任何帮助真的很感激!!!
答案 0 :(得分:0)
我使用该库时遇到了同样的问题。在我的情况下,我试图播放通过网络转发的DVB流。流是有效的,有时(由于网络问题或其他原因)某些数据包可能会丢失或损坏,并且库停止播放。
为了让它正常工作,除了&#34;视频开始时间修复&#34;之外,我还做了其他2个修复。 (帖子中的补丁)。
第一个是在解码失败时禁用&#34;停止流&#34;:
@@ -1112,7 +1127,7 @@
av_free_packet(packet_data->packet);
}
queue_pop_finish(queue, &player->mutex_queue, &player->cond_queue);
- if (err < 0) {
+ if (!player->is_live_stream && err < 0) {
pthread_mutex_lock(&player->mutex_queue);
goto stop;
}
第二个是对太晚到达的帧禁用PTS调整(在直播中我们必须删除它们):
@@ -738,7 +741,19 @@
"player_wait_for_frame[%d] Waiting for frame: sleeping: %" SCNd64,
stream_no, sleep_time);
- if (sleep_time < -300000ll) {
+ if (player->is_live_stream && sleep_time < -1000000ll) {
+ // 1000 ms late
+ int64_t new_value = player->start_time - sleep_time;
+
+ LOGI(4,
+ "player_wait_for_frame[%d] skipping frame because too late",
+ stream_no);
+
+ ret = WAIT_FUNC_RET_SKIP;
+ break;
+ }
+
+ if (sleep_time < -300000ll) {
// 300 ms late
int64_t new_value = player->start_time - sleep_time;
&#34;播放器 - &gt; is_live_stream&#34;是一个int 0/1,当我正在播放实时流时我设置为1,所以对于其他类型的源,该库仍然像以前一样工作。
希望这可以帮助你:)