I have dvblast that is successfully multicasting an MPEG2 stream originating from DVB-T onto a network, and I am trying to pick up this multicast MPEG2 stream and convert it to HLS on a Raspberry Pi 2 using gstreamer v1.0 as follows:
gst-launch-1.0 udpsrc port=5004 multicast-group=239.255.1.30 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000" ! rtpbin ! rtpmp2tdepay ! tsdemux ! mpegvideoparse ! omxmpeg2videodec ! queue ! videoconvert ! omxh264enc ! mpegtsmux ! hlssink max-files=5 location=/var/www/stream/segment%05d.ts playlist-location=/var/www/stream/output.m3u8 playlist-root=http://192.168.225.2/stream/
The HLS files are successfully created, and are served via httpd successfully to mediastreamvalidator which is happy with the results:
Processed 7 out of 7 segments: OK
Segment bitrate: Average: 430.90 kbits/sec, Max: 741.38 kbits/sec
The MPEG2 license is in place and works.
Neither Safari nor an iPhone can view this stream, in both cases the play button appears but no video or audio pays. Eventually Safari will claim "Missing plugin". I am struggling to see where I have gone wrong, and am struggling to find any documentation or examples on this specific scenario. Can anyone point out where in the pipeline this has gone wrong?
Discovered that the current gstreamer gst-omx code doesn't handle include AU delimiters, and the following patch is required to make omxh264enc generate a stream that Safari and/or iOS will play:
https://bugzilla.gnome.org/show_bug.cgi?id=736211
Using the June 9 2015 version of mediastreamvalidator shows the following issues, but the stream does now play on Safari and iOS:
WARNING: Video segment does not contain an IDR frame
--> Track ID 1
ERROR: (-12642) Playlist vs segment duration mismatch
--> Segment duration 4.7600, Playlist duration: 2.4000
Related
I'm reading a byte-stream YUV420 at 972x720 pixels from a file with Gstreamer using the following command:
gst-launch-1.0 filesrc location=testfile blocksize=1049760 ! rawvideoparse width=972 height=720 framerate=1/1 ! xvimagesink
This works in so far that I get an image but it isn't displayed correctly. When exporting the frames seperately using command:
gst-launch-1.0 filesrc location=testfile blocksize=1049760 ! rawvideoparse width=972 height=720 framerate=1/1 ! multifilesink location="rvp_%d.raw"
I see that when using the element 'rawvideoparse' it will create a file of 1051200 bytes per frame instead of the expected 1049760. When I remove 'rawvideoparse' the frames are exported correctly but my objective is to read them directly from the file into an 'xvimagesink'
Where am I messing up?
Thanks to the GStreamer Development mailing list I got an answer. The problems was that the rawvideoparse element can't handle this resolution. When I switched to 976 width it works.
I am very much new to the whole GStreamer-thing, therefore I would be happy if you could help me.
I need to stream a near-zero-latency videosignal from a webcam to a server and them be able to view the stream on a website.
The webcam is linked to a Raspberry Pi 3, because there are space-constraints on the mounting plattform. As a result of using the Pi I really can't transcode the video on the Pi itself. Therefore I bought a Logitech C920 Webcam, which is able to output a raw h264-stream.
By now I managed to view the stream on my windows-machine, but didn't manage to get the whole website-thing working.
My "achivements":
Sender:
gst-launch-1.0 -e -v v4l2src device=/dev/video0 ! video/x-h264,width=1920,height=1080,framerate=30/1 ! rtph264pay pt=96 config-interval=5 mtu=60000 ! udpsink host=192.168.0.132 port=5000
My understanding of this command is: Get the signal of video-device0, which is a h264-stream with a certain width, height and framerate. Then pack it into a rtp-package with a high enough mtu to have no artefacts and capsulate the rtp-package into a udp-package and stream in to a ip+port.
Receiver:
gst-launch-1.0 -e -v udpsrc port=5000 ! application/x-rtp, payload=96 ! rtpjitterbuffer ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false
My understanding of this command is: Receive a udp-package at port 5000. Application says it is a rtp-package inside. I don't know what rtpjitterbuffer does, but it reduces the latency of the video a bit.
rtph264depay says that inside the rtp is a h264-encoded stream. To get the raw data, which fpsdisplaysink understands we need to decode the h264 signal by the use of avdec_h264.
My next step was to change the receiver-sink to a local tcp-sink and output that signal with the following html5-tag:
<video width=320 height=240 autoplay>
<source src="http://localhost:#port#">
</video>
If I view the website I can't see the stream, but I can view the videodata, which arrived as plain text, when I analyse the data.
Am I missing a videocontainer like MP4 for my video?
Am I wrong with decoding?
What am I doing wrong?
How can I improve my solution?
How would you solve that problem?
Best regards
I'm trying to get UPNP streaming to work. Rygel runs fine, however, all I get is a mono stream, even if the input is stereo. Doing some debugging, I replicated Rygel's gstreamer pipeline with
gst-launch-1.0 pulsesrc device=upnp.monitor num-buffers=100 ! audioconvert ! lamemp3enc target=quality quality=6 ! filesink location=test.mp3
where the problem is also apparent:
mp3info -x test.mp3
...
Media Type: MPEG 1.0 Layer III
Audio: Variable kbps, 44 kHz (mono)
...
Where does this pipeline lose the second channel? How can I debug this?
You never ask for stereo:
gst-launch-1.0 pulsesrc device=upnp.monitor num-buffers=100 ! "audio/x-raw,channels=2" ! audioconvert ! lamemp3enc target=quality quality=6 ! filesink location=test.mp3
Add a -v to the launch-line to see all the caps negotiated on all pads of the pipeline. Look for "channels" and see where it goes from 2 to 1.
I am trying to run certain pipelines on the Command prompt for playing a video and I am often getting these errors/messages/warnings :
WARNING: erroneous pipeline: no element "qtdemux"
WARNING: erroneous pipeline: no element "playbin2"
WARNING: erroneous pipeline: no element "decodebin2"
ERROR: pipeline could not be constructed: no element "playbin".
Following are the pipelines :
gst-launch filesrc location=path to the mp4 file ! playbin2 ! queue ! ffmpegcolorspace ! autovideosink
or
gst-launch -v filesrc location=path to the mp4 file ! qtdemux name=demuxer ! { queue ! decodebin ! sdlvideosink } { demuxer. ! queue ! decodebin ! alsasink }
or
gst-launch -v playbin uri=path to the mp4 file
or
gst-launch -v playbin2 uri=path to the mp4 file
Questions
I wanted to know, if I am I missing the plugins to execute this.
How do I know which plugin is responsible for which or found where?
What is the benefit of implementing the pipeline via c code.Are the missing plugins still required.
Is it good to install the missing plugins form the Synaptic manager or form the Gstreamer site(base,good,bad,ugly)
When we do gst-inspect we get output like this:
postproc: postproc_hdeblock: LibPostProc hdeblock filter
libvisual: libvisual_oinksie: libvisual oinksie plugin plugin v.0.1
flump3dec: flump3dec: Fluendo MP3 Decoder (liboil build)
vorbis: vorbistag: VorbisTag
vorbis: vorbisparse: VorbisParse
vorbis: vorbisdec: Vorbis audio decoder
vorbis: vorbisenc: Vorbis audio encoder
coreindexers: fileindex: A index that stores entries in file
coreindexers: memindex: A index that stores entries in memory
amrnb: amrnbenc: AMR-NB audio encoder
amrnb: amrnbdec: AMR-NB audio decoder
audioresample: audioresample: Audio resampler
flv: flvmux: FLV muxer
flv: flvdemux: FLV Demuxer
What does the x : y ( x and y mean ) ?
Answers,
It looks like gstreamer at your ends was not installed correctly. playbin2, decodebin2 are basic and part of the base plugins
1 Yes you may be missing some plugins
2 Use gst-inspect command to check if it is available
3 From C code you can manage states, register callback, learn more
Yes missing plugins are still required
4 I guess gstreamer site would be better
5 Not sure about this one, would help if you arrange the result in a proper way
Most probably the GST_PLUGIN_PATH is incorrect. Please set the correct path to where the gstremer has been installed.
I'm constructing a gstreamer pipeline that receives two RTP streams from an networked source:
ILBC Audio stream + corresponding RTCP stream
H263 Video stream + corresponding RTCP stream
Everything is put into one gstreamer pipeline so it will use the RTCP from both streams to synchronize audio/video. So far I've come up with this (using gst-launch for prototyping):
gst-launch -vvv gstrtpbin name=rtpbin
udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-2000" port=40000 ! rtpbin.recv_rtp_sink_0
rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink
udpsrc port=40001 ! rtpbin.recv_rtcp_sink_0
rtpbin.send_rtcp_src_0 ! udpsink port=40002 sync=false async=false
udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)PCMU,encoding-params=(string)1,octet-align=(string)1" port=60000 rtpbin.recv_rtp_sink_1
rtpbin. ! rtppcmudepay ! autoaudiosink
udpsrc port=60001 ! rtpbin.recv_rtcp_sink_1
rtpbin.send_rtcp_src_1 ! udpsink port=60002 sync=false async=false
This pipeline works well if the networked source starts out with sending both video and audio. If the videostream is paused later on, gstreamer will still playback audio and even will start playing back the video when the networked source resumes the video stream.
My problem is however that if the networked source starts out with only an audio stream (video might be added later on), the pipeline seems to pause/freeze until the video stream starts as well.
Since video is optional (and can be added/removed at will by the user) in my application, is there any way I can hook up for instance an 'videotestsrc' that will provide some kind of fallback video data to keep the pipeline running when there is no networked video data?
I've tried experimenting with 'videotestsrc' and a thing called 'videomixer' but I think that mixer still requires both streams to be alive. Any feedback is greatly appreciated!
I present a simple function for pause resume by changing bins. In the following example I provide the logic to change destination bin on the fly dynamically. This shall not completely stop the pipeline which is what you seek I believe. A similar logic could be used for src bins. Here you may remove your network source bin and related decoder/demux bins and add videotestsrc bins.
private static void dynamic_bin_replacement(Pipeline pipe, Element src_bin, Element dst_bin_new, Element dst_bin_old) {
pipe.pause();
src_bin.unlink(dst_bin_old);
pipe.remove(dst_bin_old);
pipe.add(dst_bin_new);
dst_bin_new.syncStateWithParent();
src_bin.link(dst_bin_new);
pipe.ready();
pipe.play();
}
The other logic you may want to try is "PADLOCKING". Please take a look at the following posts
http://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-block.txt
and
http://web.archiveorange.com/archive/v/8yxpz7FmOlGqxVYtkPb4
and
Adding and removing audio sources to/from GStreamer pipeline on-the-go
UPDATE
Try output-selector and input-selector bins as they seem to be better alternative. I found them most reliable and have had immense luck with them. I use fakesink or fakesrc respectively as the other end of the selector.
valve bin is another alternative that I found doesn't even need fakesink or fakesrc bins. It is also extremely reliable.
Also the correct state transition order for media file source
NULL -> READY -> PAUSED -> PLAYING (Upwards)
PLAYING -> PAUSED -> READY -> NULL (Downwards)
My order in the above example should be corrected where ready() should come before pause(). Also I would tend to think un-linking should be performed after null() state and not after pause(). I haven't tried these changes but theoretically they should work.
See the following link for detailed info
http://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-states.txt?h=BRANCH-RELEASE-0_10_19