Thursday, September 27, 2012

Audio over RTP(real time protocol) using Gstreamer java

Just a test code. If it does something bad..don blame me :) .

Port used is 5000

package com.xxxxxxxxxxxxxx;

import java.util.logging.Logger;

import org.gstreamer.Bus;
import org.gstreamer.Element;
import org.gstreamer.Element.PAD_ADDED;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
import org.gstreamer.GstObject;
import org.gstreamer.Pad;
import org.gstreamer.Pipeline;
import org.gstreamer.State;
import org.gstreamer.elements.good.RTPBin;
import org.gstreamer.lowlevel.MainLoop;

/**
 * Sends audio over rtp
 *
 * use this command to test on remote host
 *      gst-launch-0.10 -v udpsrc port=5000 ! "application/x-rtp,media=(string)audio, clock-rate=(int)44100, width=16, height=16, encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1, channel-positions=(int)1, payload=(int)96" ! rtpL16depay ! audioconvert ! autoaudiosink
 *
 * @author skhurana
 *
 */
public class HWRtp {

    private static Logger logger = Logger.getLogger("HW") ;
    private static final String REMOTE_HOST = "hostIPAddressWhereStreamingWillHappen" ;
   
    public static void main(String[] args) {
        final MainLoop loop = new MainLoop();
        args = Gst.init("RtpUtil", args);
        logger.info("Gstreamer version is " + Gst.getVersionString());
        Element source, demuxer,  conv, sink ;
        final Element decoder ;
        Bus bus;
        Pipeline pipeline  ;
       
        pipeline = new Pipeline("audio-player") ;
        source = ElementFactory.make("filesrc", "file-source") ;
        demuxer = ElementFactory.make("oggdemux", "ogg-demuxer") ;
        decoder = ElementFactory.make("vorbisdec", "vorbis-decoder") ;
        // audioconvert - Convert audio to different formats.
        conv = ElementFactory.make("audioconvert", "converter") ;
       
       
        // setup the pipeline
        source.set("location", "/home/skhurana/rtx/mediacontent/test.ogg") ;
        // add message handler
        //TODO - Do something with loop here
        bus = pipeline.getBus() ;
        bus.connect(new Bus.EOS() {
            public void endOfStream(GstObject source) {
                logger.info(" End of stream reached, source is...." + source.getName()) ;
                loop.quit() ;
                loop.dispose();
            }
        }) ;
       
        bus.connect(new Bus.ERROR() {
            public void errorMessage(GstObject source, int code, String message) {
                // TODO Auto-generated method stub
                logger.info(" Error occurred, code is " + code + ". Message is " + message) ;
            }
        }) ;
       
        // do rtp stuff now
        // ************* rtp stuff starts
        // create rtpbin
        RTPBin rtpbin = new RTPBin("audio-rtp") ;
        // create udpsink - send data over network via udp
        Element udpSink_rtpout = ElementFactory.make("udpsink", "udpsink0") ;
        udpSink_rtpout.set("host", REMOTE_HOST) ;
        udpSink_rtpout.set("port", 5000) ;
       
        // rtpL16pay - payload encode raw audio over rtp packets
        Element rtpL16pay = ElementFactory.make("rtpL16pay", "rtpPay") ;
        // ************** rtp stuff ends
       
        // add all elements into a pipeline
        pipeline.addMany(source, demuxer, decoder, conv, rtpL16pay, rtpbin, udpSink_rtpout) ;
       
       
        // link the elements together
        Element.linkMany(source, demuxer) ;
        Element.linkMany(decoder, conv, rtpL16pay) ;
        // link to rtp
        logger.info("Linking pads ....") ;
        Element.linkPads(rtpL16pay, "src", rtpbin, "send_rtp_sink_0") ;
        Element.linkPads(rtpbin, "send_rtp_src_0", udpSink_rtpout, "sink") ;
       
       
        demuxer.connect(new PAD_ADDED() {
            public void padAdded(Element element, Pad pad) {
                logger.info("Dynamic pad added, linking demuxer/decoder") ;
                Pad sinkPad = decoder.getStaticPad("sink") ;
                Element.linkPads(element, pad.getName(), decoder, sinkPad.getName()) ;
            }
        }) ;
       
       
        // note that demuxer will be linked to decoder dynamically. The reason is that
        // Ogg may contain various streams e.g. audio and video.
        // The source pad(s) will be created at run time, by the demuxer when it detects
        // the amount and nature of streams.
       
        // set the pipeline to playing state
        logger.info(" pipeline now playing....and ") ;
        pipeline.setState(State.PLAYING) ;
        logger.info(" Pipeline state is " + pipeline.getState()) ;
       
       
        loop.run() ;
        //TODO - What do I do here ?
        logger.info(" returned ..stopping playback") ;
        pipeline.setState(State.NULL) ;
       
       
       
    }
}