rtsp java sample

483 views
Skip to first unread message

Farshid Bakhtyari

unread,
Apr 18, 2018, 1:37:32 PM4/18/18
to gstreamer-java
Hello All,

I have the following command that runs fine on the command line:

gst-launch-1.0 -e  rtspsrc location="rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1" ! rtph264depay ! h264parse  ! decodebin ! x264enc ! mp4mux ! filesink location=./Users/farshid/src/video_4_1723IPIP.mp4


I can see the video on my computer screen and the mp4 file gets created fine, which I can replay it.  All is good so far. 


Then I tried to port that command line (the above one) to a sample java code and get it working as a Java APP, which is not working.  When I run the app, a window opens up but it's blank and a file gets created but that one is also empty (Zero bytes). 


 Any help would greatly be appreciated.


Thanks in advance,

Farshid 


Here is the code: 


public class MultiSinkExample2 {


/**

* @param args the command line arguments

*/

private static Pipeline mainPipe;

//private Logger log = LogUtils.getLogger();

/*

*setupAllElements: creates All the elements and link them together  

*/


private static Pipeline setupAllElements(SimpleVideoComponent argVideoComponent){


//Create a pipeline first

Pipeline myTestPipeLine = new Pipeline("IPCamera");



//This is what I am trying to build in Java, it runs fine on the command line:

//gst-launch-1.0 -e  rtspsrc location="rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1" ! rtph264depay ! h264parse  ! decodebin ! x264enc ! mp4mux ! filesink location=./Users/farshid/src/video_4_1723IPIP.mp4 


//Creating the source 

Element ipCameraSource = ElementFactory.make("rtspsrc", "ipCameraSource" );

ipCameraSource.set("location", "rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1");


//Creating the other elements

Element rtpdepay = ElementFactory.make("rtph264depay", "rtpdepay"); 

Element h264 = ElementFactory.make("h264parse", "h264"); 

Element decode  = ElementFactory.make("decodebin", "decode");

Element x264  = ElementFactory.make("x264enc", "x264");

Element mux  = ElementFactory.make("mp4mux", "mux");

Element fsink  = ElementFactory.make("filesink", "fsink");

fsink.set("location","./IPvideoIPIP.mp4" );


//Adding all the elements 

myTestPipeLine.addMany(ipCameraSource, rtpdepay, h264, decode, x264, mux, fsink, argVideoComponent.getElement());


//Link all the elements

Element.linkMany(ipCameraSource, rtpdepay, h264, decode, x264, mux, fsink, argVideoComponent.getElement());

ipCameraSource.connect(new Element.PAD_ADDED() {

//I am doing this in case the source pad is not available at start.

            @Override

public void padAdded(Element element, Pad pad) {

                System.out.println("New Pad " + pad.getName() + " was created");

                Element.linkMany(ipCameraSource, rtpdepay, h264, decode, x264, mux, fsink, argVideoComponent.getElement());

             }

         });


return  myTestPipeLine

}



/*

* Main function

*/

public static void main(String[] args) {


Gst.init();


//This invokes later

EventQueue.invokeLater(new Runnable() {


@Override

public void run() {

SimpleVideoComponent vc = new SimpleVideoComponent();


mainPipe = setupAllElements(vc);

       

JFrame f = new JFrame("IP Camera Test");

f.add(vc);

vc.setPreferredSize(new Dimension(640, 480));

f.pack();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


mainPipe.play();

f.setVisible(true);

            f.addWindowListener(new java.awt.event.WindowAdapter() {

                @Override

                public void windowClosing(java.awt.event.WindowEvent windowEvent) {

                System.out.println("Window is closed I am closing the Pipe!");

                mainPipe.stop();

                }

            });

}

});


}


}

Neil C Smith

unread,
Apr 18, 2018, 2:17:19 PM4/18/18
to gstream...@googlegroups.com
Hi,

On Wed, 18 Apr 2018 at 18:37 Farshid Bakhtyari <farsh...@gmail.com> wrote:

//Adding all the elements 

myTestPipeLine.addMany(ipCameraSource, rtpdepay, h264, decode, x264, mux, fsink, argVideoComponent.getElement());


//Link all the elements

Element.linkMany(ipCameraSource, rtpdepay, h264, decode, x264, mux, fsink, argVideoComponent.getElement());


First, let's start simply. ;-)  Use the Pipeline.launch(String description) method with the pipeline you have working in the command line (without -e)

See the multi sink example for getting a named appsink from a bin - you can use that with a top level Pipeline too - and pass that to the video component.

If you're going to move on to creating the elements manually and linking them like above, you need to read up on GStreamer's dynamic (sometimes) pads and understand why you can't link some of those elements until after the pipeline is started - see https://gstreamer.freedesktop.org/documentation/application-development/basics/pads.html

There's an example of linking a decodebin in a pad added listener here -
Some of the other elements (eg. mux) might need checking at to see if they have dynamic pads.

The good thing about using the Pipeline / Bin launch() methods is that dynamic connections are handled for you.

Best wishes,

Neil

--
Neil C Smith
Artist & Technologist

Praxis LIVE - hybrid visual IDE for creative coding - www.praxislive.org

Farshid Bakhtyari

unread,
Apr 18, 2018, 3:57:51 PM4/18/18
to gstreamer-java
Thanks Niel. 

I took your advice and  made these changes:


Bin bin = Pipeline.launch("rtspsrc location=\"rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1\"  ! rtph264depay ! h264parse  ! decodebin "

        + " ! tee name=t t. ! queue ! videoconvert ! autovideosink  "  

                    + " t. ! queue ! rtph264depay ! h264parse  ! decodebin  ! x264enc ! mp4mux! filesink location=./farshids1234.mp4 " 

                   +" t. ! queue ! videoconvert ! videoscale ! capsfilter caps=video/x-raw,width=640,height=480 ! appsink name=appsink " , true);


All I get is a blank video box. 


If I explicitly set the URI by doing :


playbin.setURI(new URI("rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1"));


and remove the :


rtspsrc location=\"rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1\"  ! rtph264depay ! h264parse  decodebin


(from the above string) 


 I get to see the camera displaying.


What is going on? WHat is wrong with the code below:  What am I doing wrong?


Bin bin = Pipeline.launch("rtspsrc location=\"rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1\"  ! rtph264depay ! h264parse  ! decodebin "

         + " ! tee name=t t. ! queue ! videoconvert ! autovideosink  "  

                    + " t. ! queue ! rtph264depay ! h264parse  ! decodebin  ! x264enc ! mp4mux! filesink location=./farshids1234.mp4 " 

                   +" t. ! queue ! videoconvert ! videoscale ! capsfilter caps=video/x-raw,width=640,height=480 ! appsink name=appsink " , true);


BTW, saving the video (filesink) didn't work in any of the above set up. 



Thanks,

Farshid 

Farshid Bakhtyari

unread,
Apr 18, 2018, 4:00:50 PM4/18/18
to gstreamer-java

I also added this so I would use the filechooser on the original code:


 SimpleVideoComponent vc = new SimpleVideoComponent((AppSink) bin.getElementByName("appsink"));

            try{

            playbin = new PlayBin("playbin");

            playbin.setVideoSink(bin);

            playbin.stop();

            playbin.setURI(new URI("rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1"));

            playbin.play();

            }catch(Exception ex){

            System.out.println("There was an error" + ex.getMessage());

            }


On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Neil C Smith

unread,
Apr 19, 2018, 8:42:13 AM4/19/18
to gstream...@googlegroups.com
On Wed, 18 Apr 2018 at 20:57 Farshid Bakhtyari <farsh...@gmail.com> wrote:

If I explicitly set the URI by doing :

playbin.setURI(new URI("rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1"));

Do you have the playbin and the pipeline in the same code?

While I'm not sure exactly why your pipeline has issues, I have just been helping someone with an issue getting rtsp working in Praxis LIVE, and the playbin approach seemed far more robust.  Some searching would suggest others having issues, and possibly uridecodebin being a better option then decodebin too.

I would go back to the multi sink example and set the playbin uri there.  If that works OK, then change the output bin to remove the extra sink and save the video there.  Or have you tried that?  I'm slightly confused now! :-\

Best wishes,

Neil
 

Jim Carroll

unread,
Apr 19, 2018, 9:26:59 AM4/19/18
to gstreamer-java
Hi Neil,

A quick related question. Do you know if there's a way to programatically determine if the pads are dynamic. Obviously gst-inspect can do it but I couldn't figure out how to do it from Java.

Thanks
Jim

Neil C Smith

unread,
Apr 19, 2018, 9:35:52 AM4/19/18
to gstream...@googlegroups.com
On Thu, 19 Apr 2018 at 14:27 Jim Carroll <jimfc...@gmail.com> wrote:
A quick related question. Do you know if there's a way to programatically determine if the pads are dynamic. Obviously gst-inspect can do it but I couldn't figure out how to do it from Java.

Not that I can think of offhand.  But you can always get a list of pads from an element or check the response when you try to link.

Best wishes,

Neil 

Farshid Bakhtyari

unread,
Apr 19, 2018, 9:58:41 AM4/19/18
to gstreamer-java
Thanks Neil.

I used the MultiSink example and had it working by setting the URI, but my goal is to create a video server that dynamically connects and forward the stream to a UDP link. There could be many cameras that reside on the network and the user should be able to connect to any of them and get a live video or have the video saved (any format, mp4 or others) on the server. That's my ultimate goal for this project. 


On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Jim Carroll

unread,
Apr 19, 2018, 11:19:49 AM4/19/18
to gstreamer-java
Just curious. Are you planning on having the user be able to use a browser to display the video? Or are you writing a fat client?

Farshid Bakhtyari

unread,
Apr 19, 2018, 11:40:35 AM4/19/18
to gstreamer-java
Via Browser. 

Jim Carroll

unread,
Apr 19, 2018, 11:51:40 AM4/19/18
to gstreamer-java

How are you planning on getting a live video stream to the browser? Did you make any decisions on what technology yet?

I've been trying to figure out the right tech to use myself. Currently playing with WebRTC via Kurento but I end up with a rather complicated system with lots of moving parts. 

Farshid Bakhtyari

unread,
Apr 19, 2018, 12:28:38 PM4/19/18
to gstreamer-java
I haven't figured that out yet.  I am trying to get the  backend working first.   That wold be my next move once I get a bug free and reliable backend.  I will be more than happy to share with you whatever I find out on the frontend/browser.  Take care, Farshid

Neil C Smith

unread,
Apr 19, 2018, 1:16:14 PM4/19/18
to gstream...@googlegroups.com
On Thu, 19 Apr 2018 at 14:58 Farshid Bakhtyari <farsh...@gmail.com> wrote:
I used the MultiSink example and had it working by setting the URI, but my goal is to create a video server that dynamically connects and forward the stream to a UDP link. There could be many cameras that reside on the network and the user should be able to connect to any of them and get a live video or have the video saved (any format, mp4 or others) on the server. That's my ultimate goal for this project.

I still think a PlayBin might be able to do this with custom sinks.  However, if not look at UIRDecodeBin instead.  There is a Java object for this, although somewhere in my code stash I also found this - there's an old thread about rtsp on here somewhere which I think it relates to.

Best wishes,

Neil


/////////


public static void main(String[] args) {

        Gst.init();

        EventQueue.invokeLater(() -> {

            vc = new SimpleVideoComponent();
            vc.setPreferredSize(new Dimension(640, 380));

            f = new JFrame("RTSP Test");
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

            Bin bin = Bin.launch("uridecodebin name=source uri=rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov ! videoconvert name=videoconvert", false);
            Pad src = bin.getElementByName("videoconvert").getStaticPad("src");
            bin.addPad(new GhostPad("src", src));

            pipe = new Pipeline();
            pipe.addMany(bin, vc.getElement());
            Pipeline.linkMany(bin, vc.getElement());

            pipe.getBus().connect((Bus.ERROR) (source, code, message) -> System.err.println(message));

            f.add(vc);
            f.pack();
            f.setVisible(true);

            pipe.play();

     }
}

///////////

Jim Carroll

unread,
Apr 19, 2018, 1:36:16 PM4/19/18
to gstreamer-java

You could also try 'rtspbin' instead of 'rtspsrc' which combines a bunch of post processing. It's working for me. Though I might try 'playbin' and see if even more can be passed off to gstreamer's built in management.

Farshid Bakhtyari

unread,
Apr 19, 2018, 1:59:29 PM4/19/18
to gstreamer-java
Thank you gentlemen,

I will try your suggestions and let you know. 

Take care,
Farshid 


On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Farshid Bakhtyari

unread,
Apr 20, 2018, 11:45:16 AM4/20/18
to gstreamer-java
Hello All,

I would appreciate if some one tell me how I can add another sink to teh following. 

This came as part of the MultiSinExample:

Bin bin = Bin.launch("tee name=t t. ! queue ! videoconvert ! autovideosink "

+ "t. ! queue ! videoconvert ! videoscale ! capsfilter caps=video/x-raw,width=640,height=480 ! appsink name=appsink"



I would like to add another sink (files ink) to it.


This is the text/string for the new sink;


! rtph264depay ! h264parse  ! decodebin ! x264enc ! mp4mux ! filesink location=./MultiSionkPlayBin.mp4"


I tried many different setups and it didn't work.


For example this one:


Bin bin = Bin.launch("tee name=t t. ! queue ! videoconvert ! autovideosink "

+ "t. ! queue ! videoconvert ! videoscale ! capsfilter caps=video/x-raw,width=640,height=480 ! appsink name=appsink"

                                 + "t. ! queue ! rtph264depay ! h264parse  ! decodebin ! x264enc ! mp4mux ! filesink location=./MultiSionkPlayBin.mp4", true);




What am I doing wrong?


I like to show and at the same time save the video.


This is the command line that worked for me saving the file:

/gst-launch-1.0 -e  rtspsrc location="rtsp://192.168.0.92/axis-media/media.amp?videocodec=h264&camera=1" ! rtph264depay ! h264parse  ! decodebin ! x264enc ! mp4mux ! filesink location=./somevideo.mp4 



Thanks,

Farshid






On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Farshid Bakhtyari

unread,
Apr 23, 2018, 8:58:53 AM4/23/18
to gstreamer-java
Hello All,

I hope you had a nice weekend. 

can anyone out there comment on my last post? What am I doing wrong by setting up the queue and the tee?

Any help would greatly be appreciate. 

Thanks,
Farshid

On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Neil C Smith

unread,
Apr 23, 2018, 11:08:49 AM4/23/18
to gstream...@googlegroups.com
Hi,

Sorry, quick answer because I'm preparing for a conference.

The playbin in that example already covers what you're trying to do as far as the decodebin.  Get the hang of using gst-inspect on the command line to look at what data types any element can accept.

I would try removing one of the existing sinks, and replace rtph264depay ! h264parse  ! decodebin with another videoconvert.

Best wishes,

Neil

--
You received this message because you are subscribed to the Google Groups "gstreamer-java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gstreamer-jav...@googlegroups.com.
To post to this group, send email to gstream...@googlegroups.com.
Visit this group at https://groups.google.com/group/gstreamer-java.
For more options, visit https://groups.google.com/d/optout.

Farshid Bakhtyari

unread,
Apr 23, 2018, 3:23:31 PM4/23/18
to gstreamer-java
Thanks for your reply. 

I have tried many different things but no luck yet. 

I hate to bother you but please let me know when you have some free time after your presentation.

Thanks,
Farshid

On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Farshid Bakhtyari

unread,
Apr 25, 2018, 9:51:52 AM4/25/18
to gstreamer-java
Hello Neil,

I hope all is well. 

I finally managed to get it working. I had to use the matroskamux, with playbin and setting the URL.

Here is my bin in case someone else is trying the same:

Bin bin = Bin.launch("tee name=t  t.  ! queue ! videoconvert ! autovideosink "

  +" t. ! queue ! videoconvert ! videoscale ! capsfilter caps=video/x-raw,width=640,height=480 ! appsink name=appsink "

  +" t. ! queue ! matroskamux ! filesink location=./MultiSinkPlayBin.mkv"

+ " t. ! queue ! matroskamux ! filesink location=./MultiSinkPlayBinCopy.mkv", true);   //Over here I am trying to create a second copy of the video. It's fine and working. 

 

Thanks for your help on this issue. 


Take care,

Farshid


On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Farshid Bakhtyari

unread,
May 8, 2018, 12:16:43 PM5/8/18
to gstreamer-java

Hello All,

I hope all is well. 

I am replying to Jim Carrol's comment earlier  on :

"How are you planning on getting a live video stream to the browser? Did you make any decisions on what technology yet?

I've been trying to figure out the right tech to use myself. Currently playing with WebRTC via Kurento but I end up with a rather complicated system with lots of moving parts. " 

This is what I did:

The video controller (closest to the cameras) captures the video from a  camera and posts it to udpsink.
The videos server ( remotely connects to the video controller) captures video via udpsrc and sends it to hlssink, that's where all the videos files are saved for a web server.
The web sever here is a Nginx machine that is configured to process the video files. 
Then the user can watch video from a browser. 

Let me know if you need more information.

Thanks,
Farshid 

PS: Thanks to those, specially Neil, who answered my questions and helped me along the way. 

On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Jim Carroll

unread,
May 8, 2018, 1:18:10 PM5/8/18
to gstreamer-java
Hi Farshid,

Thanks. How's the lag using hlssink? Does it continuously play correctly? What's your video tag in the HTML look like?

Thanks again.

Jim

Farshid Bakhtyari

unread,
May 8, 2018, 1:31:55 PM5/8/18
to gstreamer-java
Hello Jim,

My lag, right now, is about a minute. But again, I haven't done much tuning on it. I am not sure if there are some. On the HTML tag, I have not got there yet. All I did, I pointed the web browser to the  localhost:8888/playlist.m3u8 file. 
I hope this helps. 

I will let you know once I figure those out. 

Have you made any progress on your end?

Thanks,
Farshid


On Wednesday, April 18, 2018 at 1:37:32 PM UTC-4, Farshid Bakhtyari wrote:

Jim Carroll

unread,
May 8, 2018, 1:37:30 PM5/8/18
to gstream...@googlegroups.com

I got Kurento working but the solution is complicated and seem fairly brittle for a production system. I got it working with ICECast but it requires coding vp8 and using an ogg container which adds a lag of a few seconds (not good for actual live streaming). I was hoping h264 + mp4 stream. I'm going to try the new WebRTC gstreamer sink that was mentioned ( http://blog.nirbheek.in/2018/02/gstreamer-webrtc.html ) but I haven't had time yet.

--
You received this message because you are subscribed to the Google Groups "gstreamer-java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gstreamer-java+unsubscribe@googlegroups.com.
To post to this group, send email to gstreamer-java@googlegroups.com.

Farshid Bakhtyari

unread,
May 8, 2018, 1:43:03 PM5/8/18
to gstreamer-java
Thanks, Jim.

I will look at them as well.
 

Take care,
Farshid
To unsubscribe from this group and stop receiving emails from it, send an email to gstreamer-jav...@googlegroups.com.
To post to this group, send email to gstream...@googlegroups.com.

Christophe Lafolet

unread,
Aug 16, 2018, 3:48:58 PM8/16/18
to Farshid Bakhtyari, gstreamer-java
Hello,
Decodebin use dynamic pipeline, so gstreamer cant link the pipeline statically at startup
Have you try to link the h264 part after pad receive h264 data?

Envoyé depuis mon mobile Huawei


-------- Message original --------
Objet : Re: [gstreamer-java] Re: rtsp java sample
De : Farshid Bakhtyari
À : gstreamer-java
Cc :
Reply all
Reply to author
Forward
0 new messages