Зацикливание видео с помощью gstreamer и gst-launch?
Я могу воспроизвести видео в командной строке с gstreamer gst-launch
как это:
gst-launch gnlfilesource location=file:///tmp/myfile.mov start=0 duration=2000000000 ! autovideosink
Воспроизводятся первые 2 секунды файла в /tmp/myfile.mov, после чего воспроизведение видео останавливается. Есть ли способ повторить этот цикл? т.е. включи 2 секунды gnlfilesource
в видео бесконечной длины, которое воспроизводит эти 2 секунды снова и снова и снова?
6 ответов
Предполагая Баш...
Оберните это в while
-loop?
while true; do [your command]; done
где true
ничего не делает успешно, т.е.
true: true
Return a successful result.
Exit Status:
Always succeeds.
Это позволяет создавать бесконечные циклы, например
$ while true; do echo "run..."; sleep 1; done
run...
run...
run...
run...
run...
...
Если вы используете gst-launch, то вам, возможно, придется использовать while true; do [your command]; done
как заявил Фредрик. Однако, если вы заинтересованы в C-коде, я написал код, который может вам помочь. Зацикливание видео каждые 2 секунды с начала файла в конце потока первого запуска.
//(c) 2011 enthusiasticgeek
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#include <gst/gst.h>
gboolean bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
{
GstElement *play = GST_ELEMENT(data);
switch (GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:
/* restart playback if at end */
if (!gst_element_seek(play,
1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
GST_SEEK_TYPE_SET, 2000000000, //2 seconds (in nanoseconds)
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
g_print("Seek failed!\n");
}
break;
default:
break;
}
return TRUE;
}
gint
main (gint argc,
gchar *argv[])
{
GMainLoop *loop;
GstElement *play;
GstBus *bus;
/* init GStreamer */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have a URI */
if (argc != 2) {
g_print ("Usage: %s <URI>\n", argv[0]);
return -1;
}
/* set up */
play = gst_element_factory_make ("playbin", "play");
g_object_set (G_OBJECT (play), "uri", argv[1], NULL);
bus = gst_pipeline_get_bus (GST_PIPELINE (play));
gst_bus_add_watch (bus, bus_callback, play);
gst_object_unref (bus);
gst_element_set_state (play, GST_STATE_PLAYING);
/* now run */
g_main_loop_run (loop);
/* also clean up */
gst_element_set_state (play, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (play));
return 0;
}
Обновление: см. Следующую ссылку http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-dataaccess.html
[Раздел 19.1.2. Воспроизвести регион мультимедийного файла. Это может быть использовано в сопряжении с моим кодом.
Это кажется возможным с multifilesrc
плагин,
gst-launch-1.0 multifilesrc location=alien-age.mpg loop=true ! decodebin ! autovideosink
Кажется, будет добавлено еще в июне 2011 года.
- самый простой способ, но он не будет работать с медиафайлами, для которых известна "длина носителя". вы можете зацикливаться на любых видеофайлах, только если файл не содержит информации о времени или длине.
Откройте файл с помощью любого медиаплеера, если он показывает длину мультимедиа или если вы можете искать файл вперед или назад, это означает, что он знает длину мультимедиа и не будет его зацикливать.
Как конвертировать видеофайл в файл без временной дорожки (потоковый файл) с помощью GStreamer:
вам нужно запустить два конвейера в командной строке, сначала запустите рекордер:
gst-launch-1.0 udpsrc port=10600 ! application/x-rtp-stream ! rtpstreamdepay name=pay1 ! rtph264depay ! h264parse ! video/x-h264,alignment=nal ! filesink location=my_timeless_file.mp4
он запускается и ждет входящего потока.
на другом терминале запустите конвейер воспроизведения:
gst-launch-1.0 filesrc location=my_file_with_time_track ! queue ! decodebin ! videoconvert ! x264enc ! h264parse config-interval=-1 ! rtph264pay pt=96 ! rtpstreampay name=pay0 ! udpsink host=127.0.0.1 port=10600
конвейер воспроизведения запускается и в конечном итоге завершается при потоковой передаче всего файла, теперь вернитесь к первой командной строке и завершите конвейер записи с помощью Ctrl + C.
(вместо udpsrc / udpsink вы можете использовать любые другие механизмы для создания потока, например appsrc / appsink)
Теперь у вас есть новый файл, который можно использовать в цикле with:
gst-launch-1.0 multifilesrc location=my_timeless_file.mp4 loop=true ! queue ! decodebin ! videoconvert ! ximagesink
Почему
multifilesrc
не зацикливает файлы известной длины?
Поскольку, когда длина носителя известна, он отправляет сообщение EOS в нисходящем направлении и приводит к тому, что весь конвейер переходит в состояние NULL, удаляя эту информацию, когда он достигает конца файла (потока байтов), он пытается найти следующий файл для воспроизведения (помните, что это "мульти" источник файла, и по умолчанию может принимать расположение подстановочных знаков, например "image_%d.png"). Если нет подстановочного знака, указывающего на следующий файл, он возвращается к только известному файлу.
По словам людей на #gstreamer
IRC-канал, вы не можете сделать это с самим gstreamer, вам нужно что-то вне конвейера gstreamer, чтобы зациклить его.
Это не зацикливание файла в потоке на gstreamer, но я смог сделать это с опцией ffmpeg -stream_loop. https://ffmpeg.org/ffmpeg.html#Main-options
$ ffmpeg -re -stream_loop -1 -i /tmp/sample.mp4 -f rtsp rtsp://localhost:8554/stream