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) ;
       
       
       
    }
}

Sunday, January 30, 2011

Command Pattern

Why this pattern has name as 'Command' ? Because someone gives a command and not care how..who will do it...

Thursday, January 27, 2011

Visitor Pattern

Why - As per wikipedia it is "is a way of separating an algorithm from an object structure it operates on".

Lets discuss with an example

- object structure - e.g. getters and setters of a class with attributes interest, principle.
(i.e. getInterest(), getPrinciple()). Lets say the class name having these getters and setters is 'Amount'.

- algorithm to calculate the interest in a class InterestCalculator. While getting the interest from 'Amount', InterestCalculator.calculate needs to be called.

- Amount is Visitable (Visitable is interface which has 'getInterest' method)

class Amount implements Visitable {

getInterest(Visitor visitor) {
visitor.visit(this) ;
}

}

- InterestCalculator is 'Visitor' (Visitor is an interface which have visit method)

class InterestCalculator implements Visitor {

visit(Amount amount) {
// calculation goes here <<<<<<<------------
}
}

- The client (e.g. main method) has to know which visitor (i.e. intetestcalculator) to inject into the accept method.

It invokes it like
Amount a = new Amount() ;
// set values in 'a' object e.g. Principal
a.getInterest(new InterestCalculator)

Sunday, October 10, 2010

Monday, March 2, 2009

XQuery

Sometimes when u have a big XML document, you want to iterate through some elements of it.  One way of doing it is to parse it and process the needed elements. Another way might be to use XQuery/XPath. You can directly access the needed elements/attributes and their values using XQuery. 
I present an example which uses Saxon s9api. Include saxon and saxon's s9api jar in the classpath. Consider this xml string  -> 
" Abiteboul "

Suppose if we want to know the years of the book (imagine there are 100s of 1000s books in the xml, though this xml shows just 1 book). We can use the follwing java code.

Processor processor = new Processor(false);
ItemTypeFactory itf = new ItemTypeFactory(processor);
ItemType integerType = itf.getAtomicType(new QName("http://www.w3.org/2001/XMLSchema", "integer"));


DocumentBuilder builder = processor.newDocumentBuilder();
        builder.setLineNumbering(true);
        builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
        String str = " Abiteboul ";
        StringValue strVal = new StringValue(str.subSequence(0, str.length()));

        InputStream bais = new ByteArrayInputStream(str.getBytes());
        StreamSource ss = new StreamSource(bais);
XdmNode fileNode = builder.build(ss);

XPathCompiler xpc = processor.newXPathCompiler();
XPathExecutable xqe = xpc.compile("/BOOKS/BOOK/@YEAR");
XPathSelector selector = xqe.load();
selector.setContextItem(fileNode);

XdmValue val = selector.evaluate();
XdmSequenceIterator itr = val.iterator();
while(itr.hasNext()) {
XdmItem xi = itr.next();
XdmNode xn = (XdmNode) xi;
System.out.println(" Node Name " + xn.getNodeName().getLocalName());
System.out.println(" Node Value " + xn.getStringValue());

}


Note - We can read an xml saved in a file too in addition to xml in string variable as in above example.