ysaburou 0 Newbie Poster

Good morning! I have these VideoChatRTP class I got [here](Good morning! I have these VideoChatRTP class I got here (I just added the main) and an EncodingUtilClass class from here.) (I just added the main) and an EncodingUtilClass class from .

VideoChatRTP.java

import javax.media.rtp.*;
import javax.media.*;
import javax.media.protocol.*;

import java.awt.Image;
import java.io.*;
import java.net.*;
import com.sun.media.ui.*;

/**
 * A RTP over UDP player which will receive RTP UDP packets and stream
 * them to the JMF RTP Player or (RTPSM) which is not aware of the
 * underlying network/transport protocol. This sample uses the
 * interfaces defined in javax.media.rtp.RTPSocket and its related classes.
 */
public class VideoChatRTP implements ControllerListener{

    /**
     * RTP Session address, multicast, unicast or broadcast address
     */
    String address = "";
    /**
     * RTP Session port
     */
    int port = 49200;
    /**en
     * Media Type i.e. one of audio or video
     */
    String media = "video";

    /////////////DO NOT CHANGE ANYTHING BELOW THIS LINE//////////////////////////

    // our main rtpsocket abstraction to which we will create and send
    // to the Manager for appropriate handler creation
    RTPSocket rtpsocket = null;
    // the control RTPIODataSource of the RTPSocket above
    RTPPushDataSource rtcpsource = null;
    // The GUI to handle our player
    PlayerWindow playerWindow;
    // The handler created for our RTP session, as returned by the Manager
    Player player = null;
    // maximum size of buffer for UDP receive from the sockets
    private  int maxsize = 2000;

    UDPHandler  rtp = null;
    UDPHandler rtcp = null;

    public VideoChatRTP(String address, int port){

        this.address = address;
        this.port = port;
        try {
            // create the RTPSocket
            rtpsocket = new RTPSocket();
            // set its content type : rtpraw/video for a video session and
            // rtpraw/audio for an audio session
            String content = "rtpraw/" + media;
            rtpsocket.setContentType(content);
            // set the RTP Session address and port of the RTP data
            rtp = new UDPHandler(address, port);
            // set the above UDP Handler to be the sourcestream of the rtpsocket
            rtpsocket.setOutputStream(rtp);
            // set the RTP Session address and port of the RTCP data
            rtcp = new UDPHandler(address, port +1);
            // get a handle over the RTCP Datasource so that we can set
            // the sourcestream and deststream of this source to the rtcp
            // udp handler we created above.
            rtcpsource = rtpsocket.getControlChannel();
            // Since we intend to send RTCP packets from the network to
            // RTPSM and vice-versa, we need to set the RTCP UDP handler
            // as both the input and output stream of the rtcpsource.
            rtcpsource.setOutputStream(rtcp);
            rtcpsource.setInputStream(rtcp);
            // set the dynamic info on the RTPSocket, so that we can
            // playback DVI as well
            if (media.equals("audio"))
                EncodingUtil.Init(rtpsocket);
            // start & connect the RTP socket data source before creating
            // the player
            try{
                rtpsocket.connect();
                player = Manager.createPlayer(rtpsocket);
                //rtpsocket.start();
            } catch (NoPlayerException e){
                System.err.println(e.getMessage());
                //      e.printStackTrace();
                return;
            }
            catch (IOException e){
                System.err.println(e.getMessage());
                //      e.printStackTrace();
                return;
            }
            if (player != null){
                player.addControllerListener(this);
                // send this player to out playerwindow
                playerWindow = new PlayerWindow(player);
            }
        }
        catch (Exception e) { System.out.println("could not connect to RTP stream."); }

    }

    public synchronized void controllerUpdate(ControllerEvent ce) {

        if ((ce instanceof DeallocateEvent) ||
        (ce instanceof ControllerErrorEvent)){
            // stop udp handlers
            if (rtp != null)
                rtp.close();
            if (rtcp != null)
                rtcp.close();
        }

    }

    // method used by inner class UDPHandler to open a datagram or
    // multicast socket as the case maybe
    private DatagramSocket InitSocket(String sockaddress, int sockport){

        InetAddress addr = null;
        DatagramSocket sock = null;
        try{
            addr = InetAddress.getByName(sockaddress);
            if (addr.isMulticastAddress()){
                MulticastSocket msock = new MulticastSocket(sockport);
                msock.joinGroup(addr);
                sock = (DatagramSocket)msock;
            }else{
                sock = new
                DatagramSocket(sockport,addr);
            }
            return sock;
        }
        catch (SocketException e){
            e.printStackTrace();
            return null;
        }
        catch (UnknownHostException e){
            e.printStackTrace();
            return null;
        }
        catch (IOException e){
            e.printStackTrace();
            return null;
        }

    }// end of InitSocket

    //INNER CLASS UDPHandler which will receive UDP RTP Packets and
    //stream them to the handler of the sources stream. IN case of
    //RTCP , it will also accept RTCP packets and send them on the
    //underlying network.
    public class UDPHandler extends Thread implements PushSourceStream, OutputDataStream{

        DatagramSocket mysock = null;
        DatagramPacket dp = null;
        SourceTransferHandler outputhandler = null;
        String myaddress = null;
        int myport;
        boolean closed = false;

        // in the constructor we open the socket and create the main
        // UDPHandler thread.
        public UDPHandler(String haddress, int hport){

            myaddress = haddress;
            myport = hport;
            mysock = InitSocket(myaddress,myport);
            setDaemon(true);
            start();

        }

        // the main thread simply receives RTP data packets from the
        // network and transfer's this data to the output handler of
        // this stream.
        public void run(){
            int len;
            while(true){
                if (closed){
                    cleanup();
                    return;
                }
                try{
                    do{
                        dp = new DatagramPacket(new byte[maxsize],maxsize);
                        mysock.receive(dp);
                        if (closed){
                            cleanup();
                            return;
                        }
                        len = dp.getLength();
                        if (len > (maxsize >> 1))
                            maxsize = len << 1;
                    }
                    while (len >= dp.getData().length);
                }catch (Exception e){
                    cleanup();
                    return;
                }

                if (outputhandler != null)
                    outputhandler.transferData(this);
            }
        }

        public void close(){
            closed = true;
        }

        private void cleanup(){
            mysock.close();
            stop();
        }

        // methods of PushSourceStream
        public Object[] getControls() {
            return new Object[0];
        }

        public Object getControl(String controlName) {
            return null;
        }

        public  ContentDescriptor getContentDescriptor(){
            return null;
        }

        public long getContentLength(){
            return SourceStream.LENGTH_UNKNOWN;
        }

        public boolean endOfStream(){
            return false;
        }

        // method by which data is transferred from the underlying
        // network to the RTPSM.
        public int read(byte buffer[], int offset, int length) {

            System.arraycopy(dp.getData(),
            0,
            buffer,
            offset,
            dp.getLength());
            return dp.getData().length;

        }

        public int getMinimumTransferSize(){
            return dp.getLength();
        }

        public void setTransferHandler(SourceTransferHandler transferHandler){
            this.outputhandler = transferHandler;
        }

        // methods of PushDestStream used by teh RTPSM to transfer
        // data to the underlying network.
        public int write(byte[] buffer, int offset, int length) {

            InetAddress addr = null;
            try{
                addr = InetAddress.getByName(myaddress);
            }catch (UnknownHostException e){
            }
            DatagramPacket dp = new DatagramPacket(buffer,length,addr,myport);
            try{
                mysock.send(dp);
            }catch (IOException e){}
            return dp.getLength();

        }

    }

    public static void main(String[] args)
    {
        try
        {
            new VideoChatRTP("239.1.2.3", 1234);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            System.exit(0);
        }



    }

EncodingUtilClass.java

import javax.media.rtp.RTPPushDataSource;
import javax.media.rtp.RTPControl;
import javax.media.rtp.RTPSocket;
import javax.media.rtp.SessionManager;
import javax.media.Format;
import javax.media.format.AudioFormat;
public class EncodingUtil {
private static final String rtpcontrol = "javax.media.rtp.RTPControl";

public static void Init(RTPPushDataSource ds){

    RTPControl control = (RTPControl)ds.getControl(rtpcontrol);
    if (control == null){
        //System.out.println("The datasource " + ds +
        //         "\n does not support the RTPControl interface..." +
        //         "\nexiting from EncodingUtil.Init()");
        return;
    }
    Init(control);
}

    public static void Init(SessionManager mgr){

         Format format = null;

        if (mgr == null)
            return;

        format = new AudioFormat(AudioFormat.DVI, 44100, 8, 1);
        mgr.addFormat(format, 18);

    }

    public static  void Init(RTPControl control){

        Format format = null;
        if (control == null)
            return;

        format = new AudioFormat(AudioFormat.DVI, 44100, 8, 1);
        control.addFormat(format, 18);

    }

}

When I run the program, it catches the NoPlayerException and prints Cannot find a Player for: javax.media.rtp.RTPSocket@1eb0.
Whole error message if printStackTrace:

Cannot find a Player for: javax.media.rtp.RTPSocket@1dee400
javax.media.NoPlayerException: Cannot find a Player for: javax.media.rtp.RTPSocket@1dee400
    at javax.media.Manager.createPlayerForSource(Manager.java:1512)
    at javax.media.Manager.createPlayer(Manager.java:500)
    at VideoChatRTP.<init>(VideoChatRTP.java:80)
    at VideoChatRTP.main(VideoChatRTP.java:280)

I have taken into consideration the JAR files and put the jmf.properties in the same folder where the JAR files are. Please help me fix this. I'm still learning Java. Thank you in advance.

Dani AI

Generated

Quick diagnosis (what that exception means). Manager.createPlayer is throwing NoPlayerException because JMF couldn't find a Player that accepts the RTPSocket DataSource you hand it. That usually comes from one of three things: JMF/plugin discovery (classpath or jmf.properties) not set up, the DataSource reporting a content type or payload that no installed plugin/codec supports, or dynamic RTP payloads not being registered before player creation. The code posted by follows the RTPSocket sample pattern, so the environment and codec/registry are the likely culprits. (docs.oracle.com)

Checklist to run through (fast, in order)

  • Ensure the full JMF runtime is actually on the app classpath (jmf.jar plus the other JMF jars) and that native libraries (Windows DLLs or Linux .so) are available at runtime. A plain copy of jmf.properties next to your executable only helps if JMF classes can be found. Install instructions and CLASSPATH examples are in the JMF setup notes. (oracle.com)
  • Try a minimal RTP test: run JMStudio or call Manager.createRealizedPlayer(new MediaLocator("rtp://address:port")) to see whether JMF will create any RTP player on that machine. If that fails, the problem is installation/codec discovery, not your RTPSocket wiring. (oracle.com)

Deeper debugging and fixes

  • If the remote stream uses a dynamic payload number (common with many modern codecs), register the mapping before creating the Player (RTPManager/SessionManager or RTPControl addFormat/addFormat calls). The EncodingUtil in the posted code only runs for audio, so a video stream with dynamic payload needs explicit registration. (docs.oracle.com)
  • Use PlugInManager / JMFRegistry to list installed codecs and plugins so you can see whether a handler for the reported content type exists. If the player list is empty for that content type, JMF cannot assemble a pipeline. (docs.oracle.com)

If fixing the environment is not feasible
JMF is very old and its RTP/codec support is limited (see the supported-RTP formats). For reliable modern RTP and wider codec support consider maintained alternatives such as vlcj (LibVLC bindings) or GStreamer Java bindings. These are actively maintained and handle current codecs/containers much more robustly. (oracle.com)

Summary for the posted snippet: confirm JMF jars/native libs are on the runtime classpath, make sure jmf.properties is visible to that runtime, check plugins with PlugInManager/JMFRegistry, and register any dynamic payload mappings before calling Manager.createPlayer.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.