Я добавил опцию start-offset
в свое приложение C ++, используя библиотеку GStreamer. По сути, оно говорит приложению запускать видео в середине, а не воспроизводить его с самого начала.
Конвейер создается следующим образом: filesrc location="file_path" ! qtdemux ! h264parse ! mppvideodec ! waylandsink
. Это то, что дает мне лучшие результаты на моем оборудовании, и я работаю под Уэстоном (Wayland)
Я выполняю поиск с простым gst_element_seek
на конвейере. Сначала я попытался дождаться, пока конвейер изменит состояние на PLAYING
или PAUSED
в шине, а затем выполнить поиск один раз. Это сработало, но на некоторых больших видео это привело к тому, что после запуска приложения первый видеокадр отображается на секунду, а затем видео фактически переходит на нужную позицию. Я не хочу этого, я хотел бы перейти туда, где я хочу, не показывая ничего другого раньше.
Поэтому я изменил свой метод поиска, чтобы он выполнялся еще до того, как я установил конвейер в состояние PLAYING
, как this:
// seek if needed
if(startTime > 0) {
// First set pipeline to PAUSED and wait for async state change
gst_element_set_state(m_pipeline, GST_STATE_PAUSED);
gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
if (!gst_element_seek (m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, startTime, GST_SEEK_TYPE_NONE, -1)) {
g_print ("Seek failed!\n");
}
gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE); // wait for seek to finish and then set to PLAYING
}
m_ret = gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
if (m_ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(m_pipeline);
exit(0);
}
И хотя это также работает, к сожалению, оно дает тот же эффект, что и раньше ... первый кадр все еще отображается, даже если поиск происходит до запуска конвейера.
Как я могу убедиться, что ничего не отображается до тех пор, пока поиск фактически не будет выполнен?
Обновление Я не мог найти какой-либо метод поиска, чтобы работать так, как я хотел, но я достиг Эффект, установив show-preroll-frame
на GstVideoSink перед построением конвейера, вот так:
m_sink = gst_element_factory_make("waylandsink", "sink");
g_object_set(m_sink, "show-preroll-frame", FALSE, NULL); // prevent preroll frame when seeking
И это работает! Я буду использовать это сейчас, если нет лучшего способа. Поиск все еще выполняется в состоянии PAUSED
, но видео отображается непосредственно из точки поиска.