VideoChatRTP
课程here(我刚刚添加了main
)和来自here的EncodingUtilClass
课程。 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);
}
}
当我运行该程序时,它会捕获NoPlayerException
并打印Cannot find a Player for: javax.media.rtp.RTPSocket@1eb0
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)
我已经考虑了JAR文件并将jmf.properties
放在JAR文件所在的同一文件夹中。请帮我解决这个问题。我还在学习Java。提前谢谢。