qasitouch
asked on
video not played using JMF while tramitting stream over RTP
I am using code to tranmit video using RTP using JMF and i am able to successfully get the video on client side
Code to send the video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVTransmit2.java
code to recieve video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVReceive.html#source
My problem is i am not able to play video in AVTransmit2.java.
If i create a player using datasouce, eigther i get player already occupied or a black screen.
please help me running the video on Transmit side as well.
NOTE: i am using web cam for video source
Code to send the video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVTransmit2.java
code to recieve video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVReceive.html#source
My problem is i am not able to play video in AVTransmit2.java.
If i create a player using datasouce, eigther i get player already occupied or a black screen.
please help me running the video on Transmit side as well.
NOTE: i am using web cam for video source
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
package secure.tech.studio.app.dev
import java.awt.Component;
import java.awt.Dimension;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLExcep
import java.util.Iterator;
import java.util.Vector;
import javax.media.CannotRealizeE
import javax.media.CaptureDeviceI
import javax.media.CaptureDeviceM
import javax.media.Codec;
import javax.media.Control;
import javax.media.Controller;
import javax.media.ControllerClos
import javax.media.ControllerEven
import javax.media.ControllerList
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerExcept
import javax.media.NoProcessorExc
import javax.media.NotRealizedErr
import javax.media.Owned;
import javax.media.Player;
import javax.media.Processor;
import javax.media.control.Qualit
import javax.media.control.TrackC
import javax.media.format.VideoFo
import javax.media.protocol.Conte
import javax.media.protocol.DataS
import javax.media.protocol.PushB
import javax.media.protocol.PushB
import javax.media.rtp.RTPManager
import javax.media.rtp.SendStream
import javax.media.rtp.SessionAdd
import javax.media.rtp.rtcp.Sourc
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
* @author Waqas Sadiq
* @project securestudioutil
* @date Dec 22, 2009
*/
public class ServerTransmision extends JPanel{
// Can be a file or http or capture source
private MediaLocator locator;
// OR
// if no web cam attached, otherwise comment below statement
// private MediaLocator locator = new MediaLocator("file:/C:/Clo
private String ipAddress = "172.16.20.244"; //destination client IP
private int portBase = 22222;
private Processor processor = null;
private RTPManager rtpMgrs[];
private DataSource dataOutput = null;
public ServerTransmision() {
initialize();
}
/**
* cature the media device and set the locator
*/
private void initialize() {
Vector devices = CaptureDeviceManager.getDe
CaptureDeviceInfo cdi = null;
for (Iterator i = devices.iterator(); i.hasNext();) {
cdi = (CaptureDeviceInfo) i.next();
if (cdi.getName().startsWith(
break;
}
if (locator == null) {
locator = cdi.getLocator();
}
}
public ServerTransmision(MediaLoc
Format format) {
this.locator = locator;
this.ipAddress = ipAddress;
Integer integer = Integer.valueOf(pb);
if (integer != null)
this.portBase = integer.intValue();
}
/**
* Starts the transmission. Returns null if transmission started ok.
* Otherwise it returns a string with the reason why the setup failed.
*/
public synchronized String start() {
String result;
result = createProcessor();
if (result != null)
return result;
// Create an RTP session to transmit the output of the
// processor to the specified IP address and port no.
result = createTransmitter();
if (result != null) {
processor.close();
processor = null;
return result;
}
// Start the transmission
processor.start();
return null;
}
/**
* Stops the transmission if already started
*/
public void stop() {
synchronized (this) {
if (processor != null) {
processor.stop();
processor.close();
processor = null;
for (int i = 0; i < rtpMgrs.length; i++) {
rtpMgrs[i].removeTargets("
rtpMgrs[i].dispose();
}
}
}
}
private String createProcessor() {
if (locator == null)
return "Locator is null";
DataSource ds;
DataSource clone;
try {
ds = Manager.createDataSource(l
//create player pop
createPlayer(Manager.creat
} catch (Exception e) {
return "Couldn't create DataSource";
}
// Try to create a processor to handle the input media locator
try {
processor = Manager.createProcessor(ds
} catch (NoProcessorException npe) {
return "Couldn't create processor";
} catch (IOException ioe) {
return "IOException creating processor";
}
// Wait for it to configure
boolean result = waitForState(processor, Processor.Configured);
if (result == false)
return "Couldn't configure processor";
// Get the tracks from the processor
TrackControl[] tracks = processor.getTrackControls
// Do we have atleast one track?
if (tracks == null || tracks.length < 1)
return "Couldn't find tracks in processor";
// Set the output content descriptor to RAW_RTP
// This will limit the supported formats reported from
// Track.getSupportedFormats to only valid RTP formats.
ContentDescriptor cd = new ContentDescriptor(ContentD
processor.setContentDescri
Format supported[];
Format chosen;
boolean atLeastOneTrack = false;
// Program the tracks.
for (int i = 0; i < tracks.length; i++) {
Format format = tracks[i].getFormat();
if (tracks[i].isEnabled()) {
supported = tracks[i].getSupportedForm
// We've set the output content to the RAW_RTP.
// So all the supported formats should work with RTP.
// We'll just pick the first one.
if (supported.length > 0) {
if (supported[0] instanceof VideoFormat) {
// For video formats, we should double check the
// sizes since not all formats work in all sizes.
chosen = checkForVideoSizes(tracks[
supported[0]);
} else
chosen = supported[0];
tracks[i].setFormat(chosen
System.err
.println("Track " + i + " is set to transmit as:");
System.err.println(" " + chosen);
atLeastOneTrack = true;
} else
tracks[i].setEnabled(false
} else
tracks[i].setEnabled(false
}
if (!atLeastOneTrack)
return "Couldn't set any of the tracks to a valid RTP format";
// Realize the processor. This will internally create a flow
// graph and attempt to create an output datasource for JPEG/RTP
// audio frames.
result = waitForState(processor, Controller.Realized);
if (result == false)
return "Couldn't realize processor";
// Set the JPEG quality to .5.
// setJPEGQuality(processor, 0.5f);
// Get the output data source of the processor
dataOutput = processor.getDataOutput();
return null;
}
/**
* @param ds
*/
private void createPlayer(DataSource ds) {
try {
Player player;
player = Manager.createRealizedPlay
Component video = player.getVisualComponent(
JFrame mediaFrame = new JFrame("Camera Screen");
mediaFrame.setDefaultClose
mediaFrame.add(video);
mediaFrame.setSize(300, 300);
mediaFrame.setVisible(true
player.getControlPanelComp
player.start();
} catch (NoPlayerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CannotRealizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotRealizedError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Use the RTPManager API to create sessions for each media
* track of the processor.
*/
private String createTransmitter() {
PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
PushBufferStream pbss[] = pbds.getStreams();
rtpMgrs = new RTPManager[pbss.length];
SessionAddress localAddr, destAddr;
InetAddress ipAddr;
SendStream sendStream;
int port;
SourceDescription srcDesList[];
for (int i = 0; i < pbss.length; i++) {
try {
rtpMgrs[i] = RTPManager.newInstance();
port = portBase + 2 * i;
ipAddr = InetAddress.getByName(ipAd
localAddr = new SessionAddress(InetAddress
destAddr = new SessionAddress(ipAddr, port);
rtpMgrs[i].initialize(loca
rtpMgrs[i].addTarget(destA
System.err.println("Create
+ port);
sendStream = rtpMgrs[i].createSendStrea
sendStream.start();
} catch (Exception e) {
return e.getMessage();
}
}
return null;
}
/**
* For JPEG and H263, we know that they only work for particular
* sizes. So we'll perform extra checking here to make sure they
* are of the right sizes.
*/
Format checkForVideoSizes(Format original, Format supported) {
int width, height;
Dimension size = ((VideoFormat) original).getSize();
Format jpegFmt = new Format(VideoFormat.JPEG_RT
Format h263Fmt = new Format(VideoFormat.H263_RT
if (supported.matches(jpegFmt
// For JPEG, make sure width and height are divisible by 8.
width = (size.width % 8 == 0 ? size.width
: (int) (size.width / 8) * 8);
height = (size.height % 8 == 0 ? size.height
: (int) (size.height / 8) * 8);
} else if (supported.matches(h263Fmt
// For H.263, we only support some specific sizes.
if (size.width < 128) {
width = 128;
height = 96;
} else if (size.width < 176) {
width = 176;
height = 144;
} else {
width = 352;
height = 288;
}
} else {
// We don't know this particular format. We'll just
// leave it alone then.
return supported;
}
return (new VideoFormat(null, new Dimension(width, height),
Format.NOT_SPECIFIED, null, Format.NOT_SPECIFIED))
.intersects(supported);
}
/**
* Setting the encoding quality to the specified value on the JPEG encoder.
* 0.5 is a good default.
*/
void setJPEGQuality(Player p, float val) {
Control cs[] = p.getControls();
QualityControl qc = null;
VideoFormat jpegFmt = new VideoFormat(VideoFormat.JP
// Loop through the controls to find the Quality control for
// the JPEG encoder.
for (int i = 0; i < cs.length; i++) {
if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {
Object owner = ((Owned) cs[i]).getOwner();
// Check to see if the owner is a Codec.
// Then check for the output format.
if (owner instanceof Codec) {
Format fmts[] = ((Codec) owner)
.getSupportedOutputFormats
for (int j = 0; j < fmts.length; j++) {
if (fmts[j].matches(jpegFmt))
qc = (QualityControl) cs[i];
qc.setQuality(val);
System.err.println("- Setting quality to " + val
+ " on " + qc);
break;
}
}
}
if (qc != null)
break;
}
}
}
private Integer stateLock = new Integer(0);
private boolean failed = false;
Integer getStateLock() {
return stateLock;
}
void setFailed() {
failed = true;
}
private synchronized boolean waitForState(Processor p, int state) {
p.addControllerListener(ne
failed = false;
// Call the required method on the processor
if (state == Processor.Configured) {
p.configure();
} else if (state == Processor.Realized) {
p.realize();
}
// Wait until we get an event that confirms the
// success of the method, or a failure event.
while (p.getState() < state && !failed) {
synchronized (getStateLock()) {
try {
getStateLock().wait();
} catch (InterruptedException ie) {
return false;
}
}
}
if (failed)
return false;
else
return true;
}
class StateListener implements ControllerListener {
public void controllerUpdate(Controlle
// If there was an error during configure or
// realize, the processor will be closed
if (ce instanceof ControllerClosedEvent)
setFailed();
// All controller events, send a notification
// to the waiting thread in waitForState method.
if (ce instanceof ControllerEvent) {
synchronized (getStateLock()) {
getStateLock().notifyAll()
}
}
}
}
public static void main(String[] args) {
Format fmt = null;
int i = 0;
// Create a audio transmit object with the specified params.
ServerTransmision serTransmision = new ServerTransmision();
// Start the transmission
String result = serTransmision.start();
// result will be non-null if there was an error. The return
// value is a String describing the possible error. Print it.
if (result != null) {
System.err.println("Error : " + result);
System.exit(0);
}
System.err.println("Start transmission for 60 seconds...");
// Transmit for 60 seconds and then close the processor
// "Stop" button that would call stop to not transmit media anymore
try {
Thread.currentThread().sle
} catch (InterruptedException ie) {
}
// Stops the transmission
serTransmision.stop();
System.err.println("...tra
System.exit(0);
}
}