Monday, 26 November 2012

Xuggler RTSP Source Code

I get asked for this quite a lot these days and for a spell I thought I'd deleted it but I found it again so before I lose it again here it is:



import com.xuggle.mediatool.IMediaListener;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.IError;
import com.xuggle.xuggler.demos.VideoImage;
import java.awt.image.BufferedImage;

/**
 * Small test on the Xuggler library as we try and get the cameras
 * streaming video that we can access through java.
 * @author Ryan
 */
public class XugglerVideoTest {
private static VideoImage mScreen = null;
private static IMediaListener mediaListener = new MediaListenerAdapter() {
    @Override
    public void onVideoPicture(IVideoPictureEvent event) {
         try {
            BufferedImage bi = event.getImage();
            if (bi != null)
            updateJavaWindow(bi);
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
};

/**
 * @param args
 */
public static void main(String[] args) {
    IMediaReader mediaReader = ToolFactory.makeReader("rtsp://username:password@192.168.1.127/ch1-s1");
//    IMediaReader mediaReader = ToolFactory.makeReader("cucina01.avi"); //file
    
    mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
//    mediaReader.setAddDynamicStreams(false);
    mediaReader.setQueryMetaData(false);
    mediaReader.addListener(mediaListener);
//    mediaReader.getContainer().setInputBufferLength(64000000);
//    mediaReader.getContainer().setProperty("probesize", 500000);
    
//    IMediaWriter mediaWriter = ToolFactory.makeWriter("receivedData.mp4", mediaReader);
//    mediaReader.addListener(mediaWriter);
    openJavaWindow();
    while(true){
//        System.out.println("reading packet");        
        IError err = null;
                if (mediaReader != null)
                    err = mediaReader.readPacket();
//        System.out.println("end packet");
        if(err != null ){
            System.out.println("Error: " + err);
            break;
        }
    }
    closeJavaWindow();    
}

  private static void updateJavaWindow(BufferedImage javaImage)
  {
    mScreen.setImage(javaImage);
  }

  /**
   * Opens a Swing window on screen.
   */
  private static void openJavaWindow()
  {
    mScreen = new VideoImage();
  }

  /**
   * Forces the swing thread to terminate; I'm sure there is a right
   * way to do this in swing, but this works too.
   */
  private static void closeJavaWindow()
  {
    System.exit(0);
  }
}

Every time Xuggler reads an image from the RTSP source onVideoPicture() is called and that is where we update our window with the image.

There is some lines commented out; IMediaWriter writes the images to file, System.out prints things to the console ;) and I forget what the rest are doing.

Enjoy!

Source as a zip

27 comments:

  1. Hi,

    I'm working on my final project to graduate. I have to build a videoconference app, using webcam-capture and xuggler. Now, I can save a media file but I need to send it to a central server and then broadcasting to android phones. I've tried with netty-mobicents(RTSP) but can't make work.

    Do you have any idea? Thanks.

    ReplyDelete
    Replies
    1. Check out FFMPEG, I'm pretty sure it can be used to receive and re-send streams to other locations.

      Delete
    2. Thanks! The problem is that FFMPEG needs a pre-recorded media file. I have to make a live streaming from a webcam.

      I'm trying to publish by RTMP on a red5 media server:

      IMediaWriter writer = ToolFactory.makeWriter("rtmp://localhost/oflaDemo/test");

      but xuggler is giving me this error:
      [main] ERROR com.xuggle.xuggler - URL: rtmp://localhost/oflaDemo/test; Error: could not find output format (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:513)

      Delete
    3. Are you sure you need a pre-recorded media file? The guy on this link appears to be working with 2 streams http://ffmpeg-users.933282.n4.nabble.com/Approx-15-seconds-delay-when-re-streaming-h-264-to-RTMP-td3972575.html (I haven't looked too much into restreaming and this was a short google but I'm pretty sure you can use FFMPEG as I suggest)

      Delete
    4. Ohhh but thats for restreaming, from RTMP to RTSP, but my video source is a webcam coded with xuggler h264 mp3. I'm getting frame by frame from the webcam, then coding with xuggler and now I need to transmit it instantly. Do you have an example or an idea to transmit a video getting the data from xuggler (no restreaming)??

      Delete
    5. Ok I see what you mean. I haven't looked into it before I'm afraid, only thing that I can think off the top of my head is to have a thread recording sections of footage to files and a separate thread then streaming each of the files and deleting them once it is done. Feels like more of a work around that a proper way though and obviously adds overhead.

      Delete
    6. This can be done with netty, the problem is that there's no documentation of this framework. I found a java project: flazr. That app take a media file and transmit it to a red5 media server, now I have to understand how does flazr works with netty (It is the only one implementation I could find). I just need to find out how flazr pass to netty the media data.

      http://flazr.com/
      http://netty.io/

      Delete
    7. Thanks for letting us know Brian. Best of luck. :)

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Your camera should come with some software that helps you find it on the network when it is connected. If it doesn't you can try looking at your router's configuration page and see what new address appears when you plug it in.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. You don't need to use RTSP then as your camera doesn't use it. Not used Xuggler with a built in camera before but try

      IMediaReader mediaReader = ToolFactory.makeReader(-1);

      My guess is -1 will use the first webcam it finds.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hi Ryan,
    I am working with 2 IP cameras of different makes. One of them works pretty well with the code that you have given. On the other one, I get an error stating - could not open file: rtsp://admin:admin@192.168.0.3....
    After reading a lot about this I found out that I need to somehow set the rtsp_transport value to tcp to get this camera working.

    Can you please help me by telling how it is to be done. The Xuggler documentation says that they after release 1.95 they support all AVOptions through the setProperty method. But that doesn't work for me.

    Please help me. Many thanks in advance.

    ReplyDelete
    Replies
    1. Sorry Anurag, I haven't looked at it for a while now so don't have any new information to share.

      Delete
  5. HI Rayan ,my name is anuradha,we did above code along with rtsp url,video is working fine,but we didn't get audio,could you please help me which type of code is mention in the above code for audio.

    ReplyDelete
    Replies
    1. When you grab data via RTSP you get it in a series of separate streams, an audio stream, a video stream and any other streams (like subtitles so I am told). I think Xuggler processes the audio stream as audio events but that is as much as I know as we didn't use Xuggler for processing audio.

      Delete
    2. Hi Ryan and i have one more doubt,we did above code for livestreaming.we are converting RTSP to RTMP srream through FFMPEG command i.e: ffmpeg_i
      + camurl
      + " -nr 1000 -pass 1 -c:a libvo_aacenc -f flv -r 25 -s 1280x720 -c:v libx264 -b:v 1M -preset ultrafast "
      + wowzaurl + " 2>" + fileurl;
      and also we include login screen in the above code.Now the code is working fine while i'm running.But every 20 min iam getting an error:
      Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
      By coming this error video image is hanging in IMediaReader but the wowza stream is working fine. To rectify this error we have added -Xms512M -Xmx1524M in eclipse run configurations.but still it is not resolved.can u give me any suggestions to remove that heap space.
      Can u please revert me back for this problem as soon as possible.thanking you.

      Delete
    3. bellow error is the exact error while running the application
      Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
      at com.xuggle.xuggler.video.BgrConverter.toImage(BgrConverter.java:182)
      at com.xuggle.mediatool.MediaReader.dispatchVideoPicture(MediaReader.java:600)
      at com.xuggle.mediatool.MediaReader.decodeVideo(MediaReader.java:519)
      at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:475)
      at genems.XugglerVideoTest.main(XugglerVideoTest.java:202)
      this is the error i got

      Delete
    4. Looks like there is a memory leak somewhere. You probably have to dispose of the images explicitly rather than just leaving them. Afraid I don't work with this stuff any more so don't know the solution. Good luck.

      Delete
  6. I have got a doubt,I did What u posted in RTSP code its working fine but audio is not working ,Would you please tell me .How to add Audio in this one ..Please help me yar..Iam so waiting for this ...

    ReplyDelete
    Replies
    1. When you grab data via RTSP you get it in a series of separate streams, an audio stream, a video stream and any other streams (like subtitles so I am told). I think Xuggler processes the audio stream as audio events but that is as much as I know as we didn't use Xuggler for processing audio.

      Delete
  7. Hi Ryan,

    I have a raspberry pi on which i run the following command:

    raspivid -o - -t 999999 -w 800 -h 600 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

    On my linux machine i run:
    ffplay rtsp://172.25.1.232:8554/

    I get a perfectly fine video on my machine.


    However when i am using your code in java and when i use this :

    IMediaReader mediaReader = ToolFactory
    .makeReader("rtsp://pi:raspberry@172.25.1.232:8554/");

    I get an error saying:

    could not connect to rtsp://pi:raspberry@172.25.1.232:8554/

    Any help/suggestions would be highly appreciated

    ReplyDelete
    Replies
    1. PS : I also tried this

      IMediaReader mediaReader = ToolFactory
      .makeReader("rtsp://172.25.1.232:8554/");

      Still got the same error:

      could not connect to rtsp://172.25.1.232:8554/

      Delete
    2. Sorry I didn't reply Arjun, I didn't see your comments. Not that it matters, I'm no longer in a position where I can help anyway!

      Delete
  8. i need source code for live streaming video from client to server like skype

    ReplyDelete
    Replies
    1. Then you better work hard and read lots.

      Delete