【问题标题】:HLS Playback Issues on Android with FFMPEG带有 FFMPEG 的 Android 上的 HLS 播放问题
【发布时间】:2014-02-26 19:51:04
【问题描述】:

我正在使用由 AppUnite 构建的 FFMPEG 和最新补丁来支持舞台表演,以便播放 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 方法中,但我无法找到解决方案。

我花了很多时间试图解决这个令人讨厌的问题,但到目前为止还没有成功。任何帮助都非常感谢!!!

【问题讨论】:

    标签: android ffmpeg http-live-streaming


    【解决方案1】:

    我在使用那个库时遇到了同样的问题。在我的情况下,我试图播放通过网络转发的 DVB 流。流是实时的,有时(由于网络问题或其他原因)某些数据包可能会丢失或损坏,并且库会停止播放。

    为了让它正常工作,除了“视频开始时间修复”(您帖子中的补丁)之外,我还进行了其他 2 个修复。

    第一个是禁用“解码失败时停止流”:

    @@ -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;
    

    “player->is_live_stream”是一个 int 0/1,我在播放实时流时设置为 1,因此对于其他类型的源,该库仍然像以前一样工作。

    希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-12
      • 2018-10-12
      相关资源
      最近更新 更多