ПОСТАНОВИЛИ
Я нашел свое решение, и что следует длительный пост, но, пожалуйста, голые со мной, я должен разделить мое расстройство с кем-то.
После многих других попыток багги я решил вернуться к тестированию некоторых настроек, используя gst-launch. Это помогло мне узнать, что после элемента queue, который буферизует часть, которая идет в fileink, мне нужен еще один элемент ffmpegcolorspace для настройки правильного формата видео, которое я думаю. В этот момент я не возвращался к этой штуке и не возвращал ее снова, я думал, что мне нужно «подойти», поэтому я решил попробовать его в C. В качестве примечания стороны, я не знаю, C, i может понять синтаксис, но это о нем ... и ради добра я сейчас пытаюсь научиться Haskell. Чтобы продолжить, я решил также попробовать использовать «GS.elementGetCompatiblePad» на элементе tee, поэтому я могу быть уверен, что пэды будут связаны с очередью.
: C код, который я сшил вместе это:
#include <gst/gst.h>
#include <glib.h>
int
main (int argc,char *argv[])
{
GstElement *pipeline, *source, *color, *color2 , *color3, *tee, *rQ, *vQ, *encoder, *fSink , *sink;
GMainLoop *loop;
loop = g_main_loop_new (NULL,FALSE);
/* initialize gstreamer */
gst_init(&argc,&argv);
/* creating elements */
pipeline = gst_pipeline_new("stream-pipeline");
source = gst_element_factory_make ("v4l2src","stream-source");
color = gst_element_factory_make ("ffmpegcolorspace","video-color");
tee = gst_element_factory_make ("tee","stream-tee");
rQ = gst_element_factory_make ("queue","record-queue");
vQ = gst_element_factory_make ("queue","video-queue");
encoder = gst_element_factory_make ("theoraenc","video-encoder");
fSink = gst_element_factory_make ("filesink","record-sink");
sink = gst_element_factory_make ("ximagesink","video-sink");
color2 = gst_element_factory_make ("ffmpegcolorspace","video-color2");
color3 = gst_element_factory_make ("ffmpegcolorspace","video-color3");
/*check that the elements were created */
if (!source || !color || !tee || !rQ || !vQ || !encoder || !fSink || !sink){
g_printerr("One element could not be created!");
return -1;
}
/*set file output location */
g_object_set(G_OBJECT (fSink),"location","rec",NULL);
gst_bin_add_many (GST_BIN(pipeline),
source,color,color2,color3,tee,rQ,vQ,encoder,fSink,sink,NULL);
/* get request pads */
GstPad *dPad, *rPad, *sDPad, *sRPad;
sDPad = gst_element_get_static_pad(vQ,"sink");
sRPad = gst_element_get_static_pad(rQ,"sink");
dPad = gst_element_get_compatible_pad(tee,sDPad,GST_CAPS_ANY);
rPad = gst_element_get_compatible_pad(tee,sRPad,GST_CAPS_ANY);
/*link pads*/
gst_pad_link(dPad,sDPad);
gst_pad_link(rPad,sRPad);
/*unref pads */
gst_object_unref(GST_OBJECT(dPad));
gst_object_unref(GST_OBJECT(rPad));
gst_object_unref(GST_OBJECT(sDPad));
gst_object_unref(GST_OBJECT(sRPad));
/*link elements */
gst_element_link(source,tee);
gst_element_link_many(rQ,color2,encoder,fSink,NULL);
gst_element_link_many(vQ,color3,sink),NULL;
/*set the pipeline state to playing */
gst_element_set_state(pipeline,GST_STATE_PLAYING);
g_main_loop_run (loop);
gst_element_set_state(pipeline,GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));
return 0;
}
Для того, чтобы использовать «gst_element_get_compatible_pad» я должен был сначала получить статические подушечки из элементов очереди, так что я рука, чтобы переключить эти четыре связанные линии. Я пробовал, и Абракадабра ... о нет, подождите ... начинается камера, создается файл и появляется окно с «видео», но черное окно остается черным!
Нет проблем, я говорю, запустите программу с помощью gst-debug-level = 5 (=))) да, попробуйте прочитать весь вывод. Я сдаюсь на данный момент, и я подумал, может быть, у него что-то есть сделайте так, чтобы элементы моего конвейера не работали вместе, поэтому я кодирую другой конвейер в C, но на этот раз что-то более простое с аудиофайлами.
У меня был тот же результат, поэтому я решил снова отладить tu, на этот раз с уровнем запуска 3, и я начал читать все это, строчно.
Где-то там я нашел это:
пытается связать поток двутавровые: src0 и запись-очереди: раковина
пытается связать поток двутавровые: src0 и видео-очереди: раковина
что-то противное, что здесь происходит
связанный поток двутавровые: src0 и видео-очереди: раковина, успешный
пытается связать поток двутавровые: src0 и запись очереди: тонуть
Src поток-тройник: src0 был уже связан с видео-очереди: раковина
И это сдаётся!
Думаю, я должен вернуться с помощью gst_element_get_request_pad, но разве я не пробовал это уже? Так я переключиться обратно в Vim и заменить все вхождения «gst_element_get_compatible_pad с запросом коллегой так:
sDPad = gst_element_get_static_pad(vQ,"sink");
sRPad = gst_element_get_static_pad(rQ,"sink");
dPad = gst_element_get_request_pad(tee,"src%d");
rPad = gst_element_get_request_pad(tee,"src%d");
Я смотрю на этот код, и я говорю себе:„Вы поучают“, это где все это началось ; сделайте глубокий вдох; после всего этого отладчик жалуется, поэтому я компилирую, я запускаю и Voila. Я нашел решение.
Эти четыре строки должны быть отменены, я должен был сначала получить ссылку на статические прокладки, а затем запросить ссылку на «запрос» на элементе тройника.
Я возвращаюсь к haskell счастливого человека. Я реализую свое решение, компилирую, запускаю, запускает камеру, файл создается и ... так же, как это .. ничего, даже черный экран.
Заполненный гневом, я просто прокомментирую строки, в которых я выпускаю прокладки для запроса, и решают скомпилировать и запустить еще раз, моя шея начала болеть некоторое время назад.
Снова по волшебству все работает, у меня есть видео на экране и в файле.
Я думаю, что Haskell просто любит держаться крепче, и иногда вам нужно просто пойти с чем-то, что не имеет смысла. Gstreamer docs четко заявляет о выпуске, выпуске, выпуске.
Конечный код Haskell:
module Main(main) where
import qualified Media.Streaming.GStreamer as GS
import Data.Maybe
import System.Exit
import System.Glib.MainLoop as Glib
import System.Glib.Signals as Glib
import System.Glib.Properties as Glib
makeElement:: String → String → IO GS.Element
makeElement elementType elementName = do
element ← GS.elementFactoryMake elementType (Just elementName)
case element of
Just element' → return element'
Nothing → do
putStrLn "Cannot create element!"
exitFailure
linkSPadToStaticSink::(GS.ElementClass object, GS.ElementClass elementT) ⇒ object → elementT → IO (Glib.ConnectId object)
linkSPadToStaticSink elSrc elSink = do
Glib.on elSrc GS.elementPadAdded (λpad → do
sinkPad ← GS.elementGetStaticPad elSink "sink"
GS.padLink pad (fromJust sinkPad)
return ∅)
player = do
GS.init
pipeline ← GS.pipelineNew "video-stream"
source ← makeElement "v4l2src" "video-source"
color ← makeElement "ffmpegcolorspace" "video-color"
color2 ← makeElement "ffmpegcolorspace" "video-color2"
tee ← makeElement "tee" "stream-tee"
rQ ← makeElement "queue" "record-queue"
vQ ← makeElement "queue" "video-queue"
encoder ← makeElement "y4menc" "video-encoder"
rSink ← makeElement "filesink" "record-sink"
sink ← makeElement "ximagesink" "video-sink"
let elements = [source,color,color2,encoder,rSink,vQ,rQ,sink,tee]
Glib.objectSetPropertyString "location" rSink "rec"
mapM_ (GS.binAdd (GS.castToBin pipeline)) elements
-- Get static pads from queue elements
sDPad ← GS.elementGetStaticPad vQ "sink"
sRPad ← GS.elementGetStaticPad rQ "sink"
-- Request pads from tee element
dPad ← GS.elementGetRequestPad tee "src%d"
rPad ← GS.elementGetRequestPad tee "src%d"
-- Link tee source to queue sink
GS.padLink (fromJust dPad) (fromJust sDPad)
GS.padLink (fromJust rPad) (fromJust sRPad)
GS.elementLink source color
GS.elementLink color tee
GS.elementLink vQ sink
GS.elementLink rQ color2
GS.elementLink color2 encoder
GS.elementLink encoder rSink
GS.elementSetState pipeline GS.StatePlaying
main = do
loop ← Glib.mainLoopNew Nothing False
player
Glib.mainLoopRun loop
Теперь я прошу вас, если/может я видел это?
Было ли это очевидно?
Я рад, что это заставит меня быть более осторожным и смотреть в не столь очевидные места, но ... eww.
В заключение ко всему этому я узнал о вариантах отладки gstreamer, я узнал, что он шепчет мне, и я ДОЛЖЕН слушать. Я узнал о том, что GDB вынужден использовать, потому что, когда я начал сшивать C-код, все, что я получил, было «seg fault».
Я научился любить ленивый и чистый код Хаскелла.
Немного Haskell, может быть, немного C и больше опыта. «Lost» полдня, три класса и несколько часов сна, но все-таки ... Так идет ...
Вы должны добавить свои открытия в ответ и принять этот ответ. Это не считается грубым, чтобы ответить на ваш собственный вопрос здесь - если вы оказались первыми, кто узнал, что не так, вам больше силы! –