using mpegtsmux in gstreamer's pipeline for recording video - webcam

I would like to capture a video stream (+audio) in MJPEG from my webcam into .mts container using this pipeline:
gst-launch-1.0 v4l2src do-timestamp=true device=/dev/video0 \ !
'image/jpeg,framerate=30/1,width=1280,height=720' ! videorate \
! queue ! mux2. pulsesrc do-timestamp=true \
device="alsa_input.pci-0000_00_1b.0.analog-stereo" ! \
'audio/x-raw,rate=88200,channels=1,depth=24' ! audioconvert ! \
avenc_aac compliance=experimental ! queue ! \
mux2. mpegtsmux name="mux2" ! filesink location=/home/sina/Webcam.mts
it seems that my pipeline doesn't recognize the mpegtsmux (?)
when i use avimux or even matroskamux it works but as far as I know for MPEG-TS I need to use the correct muxer which is "mpegtsmux"
This is the warning:
WARNING: erroneous pipeline: could not link queue0 to mux2
Can you please tell me what part of my pipeline is wrong? or what shall I change in order to get a timestamped video stream at the end (duration of the video must be shown when I play it via kdenlive or VLC)?
Best,
Sina

I think you are missing some encoder before mux.
Just try this without audio(added x264enc):
gst-launch-1.0 v4l2src device=/dev/video0 ! videorate ! queue ! x264enc ! mpegtsmux name="mux2" mux2. ! filesink location=bla.mts
The warning you are getting is saying it clearly.. it cannot link mux because the mux does not support capabilities image/jpeg.. just check the Capabilities section of sink pad with command:
gst-inspect-1.0 mpegtsmux
But it supports for example video/x-h264 - therefore the need for x264enc

Related

Gstreamer cant play stream from other pc: h264->rtp->udp

I want to stream a h264 video over UDP to another pc.
I am using this pipeline to produce the stream:
videotestsrc ! video/x-raw,width=400,height=400,framerate=7/1 ! videoconvert ! x264enc ! h264parse config-interval=1 ! video/x-h264,stream-format=byte-stream,alignment=nal ! rtph264pay ! udpsink host=192.168.1.100 port=2705
I can play this on the same machine (with ip address 192.168.1.100) with this pipeline:
udpsrc port=2705 ! application/x-rtp,width=400,height=400,encoding-name=H264,payload=96,framerate=7/1 ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink
But when I try to stream it from another pc to the same machine I get only this output and it waits forever:
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Redistribute latency...
Redistribute latency...
What can be the problem here?
I found the solution. A videoconvert element is needed in the playing pipeline.
The working playing pipeline is:
udpsrc port=2705 ! application/x-rtp,width=400,height=400,encoding-name=H264,payload=96,framerate=7/1 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

Gstreamer: RTP stream to VP8/webm recording does not produce a seekable file

I'm using Gstreamer to capture a WebRTC stream to a webm file. I've noticed when using VP8 encoding in an rtp stream, the file produced is not seekable in any players (Chrome or VLC for example). By seekable, I mean that you cannot play the file from an arbitrary point in the stream, it only starts from the very start when played.
I've instead used h264 encoding with rtp and the resulting mp4 file is seekable. Also, removing rtp encoding/decoding produces a seekable output file for VP8.
Here's are test pipelines to produce these results.
# produces a valid webm file that is not seekable (I need this to be seekable)
gst-launch-1.0 -e \
autovideosrc ! autovideoconvert ! vp8enc ! rtpvp8pay ! rtpvp8depay ! webmmux ! \
filesink location=test.webm
# produces a valid webm file that is seekable
gst-launch-1.0 -e \
autovideosrc ! autovideoconvert ! vp8enc ! webmmux ! \
filesink location=test.webm
# produces a valid mp4 file that is seekable
gst-launch-1.0 -e \
autovideosrc ! autovideoconvert ! x264enc ! rtph264pay ! rtph264depay ! h264parse ! mp4mux ! \
filesink location=test.mp4
Is there a method of creating a seekable rtp/VP8/matroska recording? Is this a bug in Gstreamer?
I've used both Gstreamer 1.14 and 1.18 on Ubuntu with the same results.
This is an oddity in the webm format which also affects the MediaRecorder API.
See here.
In a nutshell you need to update the duration metadata at the beginning of the file when you stop the recording.

multiple RTP Packet to each file. And Muxing

I have Janus(WebRTC) server. And I am using VP8/OPUS. Then Janus RTP Packet forwards to GStreamer. I have two questions.
Do I have to run one GStreamer(with multiple threads) or multiple GStremaer? Actually, Janus sent to Gstreamer multiple RTP streams. Ex) Two peer are in WebRTC room. Then, Janus sent 4 RTP packet to GStreamer. peer1: video/audio, peer2: video/audio. If I ran just one GStreamer, it is not possible to ascertain who each stream is from. So To classify I have to separate port with multiple GStreamer procceses.
Like this:
Process1:
gst-launch-1.0 \ rtpbin name=rtpbin \ udpsrc name=videoRTP port=5000 \ caps=“application/x-rtp, media=(string)video, payload=98, encoding-name=(string)VP8-DRAFT-IETF-01, clock-rate=90000” \ ! rtpvp8depay ! webmmux ! queue \ ! filesink location=track1.webm \ udpsrc port=5002 \ caps=“application/x-rtp, media=audio, payload=111, encoding-name=(string)OPUS, clock-rate=48000" \ ! rtpopusdepay ! opusparse ! oggmux \ ! filesink location=audio.ogg
process2:
gst-launch-1.0 \ rtpbin name=rtpbin \ udpsrc name=videoRTP port=5003 \ caps=“application/x-rtp, media=(string)video, payload=98, encoding-name=(string)VP8-DRAFT-IETF-01, clock-rate=90000” \ ! rtpvp8depay ! webmmux ! queue \ ! filesink location=track1.webm \ udpsrc port=5005 \ caps=“application/x-rtp, media=audio, payload=111, encoding-name=(string)OPUS, clock-rate=48000" \ ! rtpopusdepay ! opusparse ! oggmux \ ! filesink location=audio.ogg
So I confuse. Whether multiple threads? or multiple processes? Tell me details plz!
How do I mux VP8/OPUS to mp4 container in realtime? I searched for it for a long time. But I can't yet. GStreamer has so many options for each version.
I am waiting for your advice! Thank your.
I've tried as much as I can.
I expect way and mp4 files.
Hi one solution may be the plugin tee
found on the help pages
Description
Split data to multiple pads. Branching the data flow is useful when e.g. capturing a video where the video is shown on the screen and also encoded and written to a file. Another example is playing music and hooking up a visualisation module.
One needs to use separate queue elements (or a multiqueue) in each branch to provide separate threads for each branch. Otherwise a blocked dataflow in one branch would stall the other branches.
Example launch line
1
gst-launch-1.0 filesrc location=song.ogg ! decodebin ! tee name=t ! queue ! audioconvert ! audioresample ! autoaudiosink t. ! queue ! audioconvert ! goom ! videoconvert ! autovideosink
Play song.ogg audio file which must be in the current working directory and render visualisations using the goom element (this can be easier done using the playbin element, this is just an example pipeline).

How to stream h264 with udp gstreamer

I'm trying to stream a video with h264. Source is a Axis camera. I managed to stream jpeg with multicast but not h264.
With jpeg I used following command:
gst-launch-1.0 udpsrc uri=udp://239.194.0.177:1026 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec ! autovideosink
I tried to stream h264 but it fails, used following command:
gst-launch-1.0 -v udpsrc host=239.194.0.177 port=1026 ! rtph264depay ! ffdec_h264 ! xvimagesink
I get the following error:
ERROR: pipeline could not be constructed: no element "udpsrc".
With this line:
gst-launch-1.0 udpsrc uri=udp://239.194.0.177:1026 ! application/x-rtp,media=video,clock-rate=90000,encoding-name=H264 ! rtph264depay ! h264parse
I did not get any errors but no video streamed and this was printed in terminal:
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
I tried the commands from following pages:
Stream H.264 video over rtp using gstreamer
https://developer.ridgerun.com/wiki/index.php/Using_UDP_Multicast_with_GStreamer
http://labs.isee.biz/index.php/Example_GStreamer_Pipelines#H.264_RTP_Streaming
But could not get it to work.
When running in verbos mode I get litte more info.
Command:
gst-launch-1.0 -v udpsrc uri=udp://239.194.0.177:1026 ! application/x-rtp, media=video, payload=96, encoding-name=H264 ! rtph264depay ! avdec_h264 ! videoconvert ! fakesink
Output:
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "application/x-rtp\,\ media\=\(string\)video\,\ payload\=\(int\)96\,\ encoding-name\=\(string\)H264\,\ clock-rate\=\(int\)90000"
/GstPipeline:pipeline0/GstRtpH264Depay:rtph264depay0.GstPad:sink: caps = "application/x-rtp\,\ media\=\(string\)video\,\ payload\=\(int\)96\,\ encoding-name\=\(string\)H264\,\ clock-rate\=\(int\)90000"
How do I stream H264 via multicast with gstreamer?
Too long for comment - and since nobody is answering posting this draft of thoughts as answer..
The first error about no element udpsrc is really weird. But I think its complaining about missing uri parameter. What version are you using? I do not have the host parameter for udpsrc..
In third pipeline it ends with h264parse - is this s typo? you need to decode the h264.. not just parse it:
gst-launch-1.0 udpsrc uri=udp://239.194.0.177:1026 ! application/x-rtp,media=video,clock-rate=90000,encoding-name=H264 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
Also add some logs (maybe with pastebin if too long) with running GST_DEBUG=3 gst-launch-1.0 .... or so.
What does it mean:
But could not get it to work
This does not say too much ;)
Usually when working with rtp you need to provide really all capabilities otherwise it may not link or play at all..
Maybe try with uridecodebin? Not sure if its the best idea:
gst-launch-1.0 uridecodebin uri=udp://etcetc:port ! videoconvert ! autovideosink
If you get any new infos/questions add them as updates to make the picture whole (for others as well..)
HTH

Why can I stream h264 encoded video from webcam to BOTH display and file, but NOT raw video?

I want to stream raw video from a Logitech C920 webcam and while both displaying and saving the video to file using GStreamer 1.0.
This works if I stream h264 encoded video from the camera (the camera provides hardware encoded h264), but it fails if I stream raw video from the camera. However, if I only display, or only save to file, streaming raw video works.
Why does it work with a h264 video stream but not with a raw video stream?
h264 encoded video stream from camera to BOTH display and file (WORKS):
gst-launch-1.0 -v v4l2src device=/dev/video0 \
! video/x-h264,width=640,height=480,framerate=15/1 ! tee name=t \
t. ! queue ! h264parse ! avdec_h264 ! xvimagesink sync=false \
t. ! queue ! h264parse ! matroskamux \
! filesink location='h264_dual.mkv' sync=false
raw video stream from camera to ONLY display (WORKS):
gst-launch-1.0 -v v4l2src device=/dev/video0 \
! video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 \
! xvimagesink sync=false
raw video stream from camera to ONLY file (WORKS):
gst-launch-1.0 -v v4l2src device=/dev/video0 \
! video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 \
! videoconvert ! x264enc ! matroskamux \
! filesink location='raw_single.mkv' sync=false
raw video stream from camera to BOTH display and file (FAILS):
gst-launch-1.0 -v v4l2src device=/dev/video0 \
! video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 \
! tee name=t \
t. ! queue ! xvimagesink sync=false \
t. ! queue ! videoconvert ! x264enc ! h264parse ! matroskamux \
! filesink location='raw_dual.mkv' sync=false
The last command (raw video to both display and file) fails without any warnings or errors. The gst-launch terminal output is exactly the same as when only writing to file. The xvimage window appears and displays an image from the camera, but the image does not change (i.e. it is frozen). A zero bytes file appears too.
I have tried multiple versions of the above commands, but I think those are the minimal commands that can reproduce the problem.
Does anyone understand what I am doing wrong?
Streaming raw video from a webcam (not specific to C920) to both display and h.264 encoded file can be done. The x264enc property tune needs to be set to zerolatency.
h.264 example:
gst-launch-1.0 -v v4l2src device=/dev/video0 \
! video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 \
! tee name=t t. ! queue ! xvimagesink sync=false t. ! queue ! \
videoconvert ! x264enc tune=zerolatency ! h264parse ! \
matroskamux ! filesink location='raw_dual.mkv' sync=false
Alternatively, one can skip h.264 altogether and encode to theora or vp8 instead.
theora example:
gst-launch-1.0 -v v4l2src device=/dev/video0 ! \
video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 ! \
tee name=t t. ! queue ! xvimagesink sync=false t. ! queue ! \
videoconvert ! theoraenc ! theoraparse ! \
matroskamux ! filesink location='raw_dual.mkv' sync=false
vp8 example:
gst-launch-1.0 -v v4l2src device=/dev/video0 ! \
video/x-raw,format=YUY2,width=640,height=480,framerate=15/1 ! \
tee name=t t. ! queue ! xvimagesink sync=false t. ! queue ! \
videoconvert ! vp8enc ! \
matroskamux ! filesink location='raw_dual.mkv' sync=false
Thanks a lot to Jan Spurny and Tim.