Adding subtitle while doing H.264 encoding into a Matroska container - gstreamer

I have a requirement where I need to encode a v4l2src source in H.264 while using a Matroska container. If I have .mkv file with embedded subtitles it is easy to extract subtitles with
gst-launch-1.0 filesrc location=test.mkv ! matroskademux ! "text/x-raw" ! filesink location=subtitles
From what I understand and assuming I understand correctly, during the encoding process the "subtitle_%u" pad needs to be linked to text/x-raw source using textoverlay.
gst-launch-1.0 textoverlay text="Video 1" valignment=top halignment=left font-desc="Sans, 60" ! mux. imxv4l2src device=/dev/video0 ! timeoverlay ! videoconvert ! queue ! vpuenc_h264 ! capsfilter
caps="video/x-h264" ! matroskamux name=mux ! filesink location=sub.mkv
I use the above pipeline but I do not get the overlay in the .mkv video. What is the correct way to encode a subtitle/text overlay while encoding a source in H.264 in a matroska container and then also later be able to extract it using the first pipeline?
Sanchayan.

You may try this:
gst-launch-1.0 \
filesrc location=subtitles.srt ! subparse ! kateenc category=SUB ! mux.subtitle_0 \
imxv4l2src device=/dev/video0 ! timeoverlay ! videoconvert ! queue ! vpuenc_h264 ! \
capsfilter caps="video/x-h264" ! matroskamux name=mux ! filesink location=sub.mkv
And the subtitles.srt file may be like this:
1
00:00:00,500 --> 00:00:05,000
CAM 1
2
00:00:05,500 --> 00:00:10,000
That's all folks !

Related

gstreamer saved files have no audio

I'm trying to use this command to create multiple files from stream but they have no audio playback, I think decodebin should be dealing with it, what am I doing wrong?
gst-launch-1.0 -e filesrc location=video.mp4 ! queue ! decodebin ! queue ! videoconvert ! queue ! timeoverlay ! x264enc key-int-max=10 ! h264parse ! splitmuxsink location=videos/test%02d.mp4 max-size-time=1000000000000
Why do you make that assumption that decodebin will handle it? decodebin will decode the audio track to raw audio and exposes an audio pad. If you don't make use of that pad it will not make itself into the file.
Since you transcode you will have to re-encode the audio too:
gst-launch-1.0 -e filesrc location=video.mp4 ! queue ! decodebin ! queue ! \
videoconvert ! queue ! timeoverlay ! x264enc key-int-max=10 ! h264parse ! \
splitmuxsink location=videos/test%02d.mp4 max-size-time=1000000000000 \
decodebin0. ! queue ! voaacenc ! aacparse ! splitmuxsink0.
If you don't want to re-encode but passthrough the audio decodebin is the wrong way. parsebin may be a better fit in that case.

capture segmented audio and video with gstreamer

I'm trying to record audio and video from internal webcam and mic to segmented files with gstreamer.
It works to a single file by doing:
gst-launch-1.0 -e avfvideosrc !
video/x-raw ! vtenc_h264 ! h264parse ! queue !
mpegtsmux name=mux ! filesink location=test.mp4 osxaudiosrc !
decodebin ! audioconvert ! faac ! aacparse ! queue ! mux.
It doesn't work when doing:
gst-launch-1.0 -e avfvideosrc !
video/x-raw ! vtenc_h264 ! h264parse ! queue !
splitmuxsink
muxer=mpegtsmux
location=test%04d.mp4
max-size-time=1000000000
name=mux osxaudiosrc !
decodebin ! audioconvert ! faac ! aacparse ! queue ! mux.
saying erroneous pipeline: could not link queue1 to mux
I'm using gstreamer 1.12.3 on Mac OSX Sierra
Note: The H264/AAC encoding isn't necessary for what I want to achieve, so if there are solutions that only work with e.g. avimux, for whatever reason, that's fine.
EDIT: I've tried this on a windows machine with the same error.
gst-launch-1.0 -ev ksvideosrc ! video/x-raw !
videoconvert ! queue !
splitmuxsink max-size-time=1000000000 muxer=avimux name=mux
location=video%04d.avi autoaudiosrc !
decodebin ! audioconvert ! queue ! mux.
Just like on Mac, replacing splitmuxsink with avimux ! filesink works. I'm sure I'm just missing out on some 'pipeline' logic so any clarifiction that can push me in the right direction would be helpful.
I needed to send the audio stream to the audio track of the muxer like so: mux.audio_0
gst-launch-1.0 -ev ksvideosrc ! video/x-raw !
videoconvert ! queue !
splitmuxsink max-size-time=1000000000 muxer=avimux name=mux
location=video%04d.avi autoaudiosrc !
decodebin ! audioconvert ! queue ! mux.audio_O
This happens when the documentation should be clear but you're missing out on some basic knowledge on how to interpret it.

Gstreamer-1.0: mux raw video in a mp4 container

I have a raw video that I can play through gstreamer:
gst-launch-1.0 ... autovideoconvert ! autovideosink
I can encode this video:
gst-launch-1.0 ... ! autovideoconvert ! x264enc ! h264parse ! mp4mux ! filesink location=a.mp4
I would like now to put this raw video in a mp4 container "lossless", without any compression. How can I do that?
You answered in your question. Don't do compression
gst-launch-1.0 ... ! autovideoconvert ! mp4mux ! filesink location=a.mp4
But you know, without compression this file will be large (GBytes.)
I don't think I can use mp4mux but qtmux accept raw-uyvy. The following works:
gst-launch-1.0 ... ! autovideoconvert ! "video/x-raw,format=(string)UYVY" ! qtmux ! filesink location=a.mov
Sometimes the source data won't be suitable for re-muxing, but if it is a pipeline such as this should work:
gst-launch-1.0 filesrc location=... ! [DEMUX] ! h264parse ! qtmux !
filesink location=...
h264 data has different "stream formats" and "alignments" that it can be in. The stream formats are avc, avc3, and byte-stream. The possible alignments are au and nal. Different muxers take different combinations of these. h264parse will make that transformation if necessary.
And to re-iterate, sometimes the source data just won't be re-muxable into the desired container. It depends on a lot of factors.

Gstreamer pipeline for converting files with optional audio/video

I am using the following pipeline to convert an flv file to mp4.
gst-launch-1.0 -vvv -e filesrc location="c.flv" ! flvdemux name=demux \
demux.audio ! queue ! decodebin ! audioconvert ! faac bitrate=32000 ! mux. \
demux.video ! queue ! decodebin ! videoconvert ! video/x-raw,format=I420 ! x264enc speed-preset=superfast tune=zerolatency psy-tune=grain sync-lookahead=5 bitrate=480 key-int-max=50 ref=2 ! mux. \
mp4mux name=mux ! filesink location="c.mp4"
The problem is when (for example) audio is missing, the pipeline gets stuck. (Same thing happens if just hooking a fakesink to demux.audio).
I need a way for the filters to ignore missing tracks, or produce empty tracks.

How to extract h264 and aac elementary stream from an mp4 / mkv using gstreamer

I could not find a stable and balanced approach to demux the A/V stream and then save it as a playable h264 annex B format video.
Well, I tried the following steps for shrinkage file.
gst-launch-0.10 filesrc
location=h264_720p_mp_3.1_3mbps_aac_shrinkage.mkv ! matroskademux !
filesink location=abc.h264
-rw-rw-r-- 1 XXX XXX 28697147 Nov 1 10:04 h264_720p_mp_3.1_3mbps_aac_shrinkage.mkv
-rw-rw-r-- 1 XXX XXX 27581733 Nov 1 10:19 abc.h264
a file got saved with "not so smaller" size but is not playable, however the parent container format is playable with the following pipeline
gst-launch-0.10 filesrc
location=h264_720p_mp_3.1_3mbps_aac_shrinkage.mkv ! matroskademux !
h264parse ! ffdec_h264 ! ffmpegcolorspace ! ximagesink
Questions
Q1. What are the methods to extract the video ES and Audio ES from different containers using gstreamer ?
Q2. Q1 using some other methods which always works and/or are easy ?
In general, you need to specify which pad you're interested in. Otherwise you couldn't distinguish the audio ES from the video ES.
The following works on my machine:
gst-launch-1.0 filesrc location=example.mkv ! queue ! matroskademux name=dmux dmux.video_0 ! queue ! filesink location=vid.265 dmux.audio_0 ! queue ! filesink location=aud.aac
Following all commands works for me. It creates h.264 byte stream file from mp4 video file. Newly created file also played using ffplay or gst-play-1.0
gst-launch-1.0 filesrc location=./VID-20190903-WA0012.mp4 ! qtdemux name=pnkj_demux ! h264parse ! video/x-h264,stream-format=byte-stream ! filesink location=./VID-20190903-WA0012_1.264
gst-launch-1.0 -e filesrc location=./VID-20190903-WA0012.mp4 ! qtdemux name=pnkj_demux ! h264parse ! video/x-h264,stream-format=byte-stream ! filesink location=./VID-20190903-WA0012_2.264
gst-launch-1.0 filesrc location=./VID-20190903-WA0012.mp4 ! qtdemux name=pnkj_demux pnkj_demux.video_0 ! h264parse ! video/x-h264,stream-format=byte-stream ! filesink location=./VID-20190903-WA0012_3.264
gst-launch-1.0 -e filesrc location=./VID-20190903-WA0012.mp4 ! qtdemux name=pnkj_demux pnkj_demux.video_0 ! h264parse ! video/x-h264,stream-format=byte-stream ! filesink location=./VID-20190903-WA0012_4.264