📄 rtpexport.java
字号:
/*
* @(#)RTPExport.java 1.1 01/04/10
*
* Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*
* Mofified by Frank McCown in May 2002 for ROWC - thesis project.
*
* This object saves captured video from a web cam to a file using the QuickTime
* format.
*/
import java.awt.*;
import java.io.File;
import javax.media.*;
import javax.media.control.TrackControl;
import javax.media.control.QualityControl;
import javax.media.Format;
import javax.media.format.*;
import javax.media.datasink.*;
import javax.media.protocol.*;
import java.io.IOException;
import com.sun.media.format.WavAudioFormat;
public class RTPExport implements ControllerListener, DataSinkListener
{
private Processor processor;
private Object waitFileSync = new Object();
private boolean fileDone = false;
private boolean fileSuccess = true;
public int actualRecTime = 0;
private int duration; // Max amount of time to record
/**
* Given a source media locator, destination media locator and a duration
* this method will receive RTP transmission, transcode the source to the
* destination into a default format.
*/
public boolean startExport(DataSource ds, MediaLocator outML, int duration)
{
this.duration = duration;
Processor p;
// p = VideoTransmitter.processor;
try
{
System.err.println("- create processor for: " + ds);
p = Manager.createProcessor(ds);
processor = p;
}
catch (Exception e)
{
System.err.println("Yikes! Cannot create a processor from the given url: " + e);
return false;
}
p.addControllerListener(this);
// Put the Processor into configured state.
p.configure();
if (!waitForState(p, p.Configured))
{
System.err.println("Failed to configure the processor.");
return false;
}
// Set the output content descriptor to QuickTime format.
setContentDescriptor(p);
// Program the tracks.
if (!setTrackFormats(p))
return false;
// We are done with programming the processor. Let's just
// realize it.
p.realize();
if (!waitForState(p, p.Realized))
{
System.err.println("Failed to realize the processor.");
return false;
}
// Set the JPEG quality to .5.
setJPEGQuality(p, 0.5f);
// Now, we'll need to create a DataSink.
DataSink dsink;
if ((dsink = createDataSink(p, outML)) == null)
{
System.err.println("Failed to create a DataSink for the given output MediaLocator: " + outML);
return false;
}
dsink.addDataSinkListener(this);
fileDone = false;
// Set the stop time
p.setStopTime(new Time((double)duration));
// OK, we can now start the actual transcoding
try
{
p.start();
dsink.start();
}
catch (IOException e)
{
System.err.println("IO error during transcoding");
return false;
}
System.err.println("start transcoding for " + duration + " seconds...");
// Wait for EndOfStream event
waitForFileDone();
// Cleanup
try
{
dsink.close();
}
catch (Exception e)
{
e.printStackTrace();
}
p.removeControllerListener(this);
System.err.println("...done RTPExporting.");
return true;
}
public void stopExport()
{
System.out.println("SETTING duration = 0");
// Cause looping to stop by setting duration to zero
this.duration = 0;
}
/**
* Set the content descriptor to QuickTime format.
*/
void setContentDescriptor(Processor p)
{
ContentDescriptor cd = new FileTypeDescriptor(
ContentDescriptor.mimeTypeToPackageName("video/quicktime"));
// If the output file maps to a content type, we'll try to set it on the processor.
if (cd != null)
{
System.err.println("- set content descriptor to: " + cd);
if ((p.setContentDescriptor(cd)) == null)
{
// The processor does not support the output content
// type. But we can set the content type to RAW and
// see if any DataSink supports it.
p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW));
}
}
}
/**
* Set the target transcode format on the processor.
*/
boolean setTrackFormats(Processor p)
{
Format supported[];
TrackControl[] tracks = p.getTrackControls();
// Do we have at least one track?
if (tracks == null || tracks.length < 1)
{
System.err.println("Couldn't find tracks in processor");
return false;
}
for (int i = 0; i < tracks.length; i++)
{
if (tracks[i].isEnabled())
{
supported = tracks[i].getSupportedFormats();
if (supported.length > 0)
{
tracks[i].setFormat(supported[0]);
}
else
{
System.err.println("Cannot transcode track [" + i + "]");
tracks[i].setEnabled(false);
return false;
}
}
else
{
tracks[i].setEnabled(false);
return false;
}
}
return true;
}
/**
* 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.JPEG);
// 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(null);
for (int j = 0; j < fmts.length; j++)
{
if (fmts[j].matches(jpegFmt))
{
qc = (QualityControl)cs[i];
qc.setQuality(val);
System.err.println("- Set quality to " + val + " on " + qc);
break;
}
}
}
if (qc != null)
break;
}
}
}
/**
* Create the DataSink.
*/
DataSink createDataSink(Processor p, MediaLocator outML)
{
DataSource ds;
if ((ds = p.getDataOutput()) == null)
{
System.err.println("Something is really wrong: the processor does not have an output DataSource");
return null;
}
DataSink dsink;
try
{
System.err.println("- create DataSink for: " + outML);
dsink = Manager.createDataSink(ds, outML);
dsink.open();
}
catch (Exception e)
{
System.err.println("Cannot create the DataSink: " + e);
return null;
}
return dsink;
}
Object waitSync = new Object();
boolean stateTransitionOK = true;
/**
* Block until the processor has transitioned to the given state.
* Return false if the transition failed.
*/
boolean waitForState(Processor p, int state)
{
synchronized (waitSync)
{
try
{
while (p.getState() < state && stateTransitionOK)
waitSync.wait();
} catch (Exception e) {}
}
return stateTransitionOK;
}
/**
* Controller Listener.
*/
public void controllerUpdate(ControllerEvent evt)
{
if (evt instanceof ConfigureCompleteEvent ||
evt instanceof RealizeCompleteEvent ||
evt instanceof PrefetchCompleteEvent)
{
synchronized (waitSync)
{
stateTransitionOK = true;
waitSync.notifyAll();
}
}
else if (evt instanceof ResourceUnavailableEvent)
{
synchronized (waitSync)
{
stateTransitionOK = false;
waitSync.notifyAll();
}
}
else if (evt instanceof MediaTimeSetEvent)
{
System.err.println("- mediaTime set: " +
((MediaTimeSetEvent)evt).getMediaTime().getSeconds());
}
else if (evt instanceof StopAtTimeEvent)
{
System.err.println("- stop at time: " +
((StopAtTimeEvent)evt).getMediaTime().getSeconds());
evt.getSourceController().close();
}
}
/**
* Block until file writing is done.
*/
boolean waitForFileDone()
{
System.err.print(" ");
synchronized (waitFileSync)
{
try
{
while (!fileDone)
{
//System.out.println("duration="+duration);
//System.out.println("secs="+processor.getMediaTime().getSeconds());
if (processor.getMediaTime().getSeconds() > duration)
processor.close();
waitFileSync.wait(1000);
System.err.print(".");
}
actualRecTime = (int)Math.round(processor.getMediaTime().getSeconds());
//System.err.println("actualRecTime="+actualRecTime);
}
catch (Exception e)
{
System.err.println("");
e.printStackTrace();
}
}
System.err.println("");
return fileSuccess;
}
/**
* Event handler for the file writer.
*/
public void dataSinkUpdate(DataSinkEvent evt)
{
System.out.println("DataSinkEvent:"+evt);
if (evt instanceof EndOfStreamEvent)
{
System.out.println("EndOfStreamEvent entered");
synchronized (waitFileSync)
{
fileDone = true;
System.out.println("fileDone=true");
waitFileSync.notifyAll();
System.out.println("wailFileSync.notifyAll()");
}
}
else if (evt instanceof DataSinkErrorEvent)
{
System.out.println("DataSinkErrorEvent entered");
synchronized (waitFileSync)
{
fileDone = true;
fileSuccess = false;
waitFileSync.notifyAll();
}
}
}
/**
* Convert a file name to a content type. The extension is parsed
* to determine the content type.
*/
ContentDescriptor fileExtToCD(String name)
{
String ext;
int p;
// Extract the file extension.
if ((p = name.lastIndexOf('.')) < 0)
return null;
ext = (name.substring(p + 1)).toLowerCase();
String type;
// Use the MimeManager to get the mime type from the file extension.
if (ext.equals("mp3"))
type = FileTypeDescriptor.MPEG_AUDIO;
else
{
if ((type = com.sun.media.MimeManager.getMimeType(ext)) == null)
return null;
System.out.println("\ntype="+type+"\n");
type = ContentDescriptor.mimeTypeToPackageName(type);
}
System.out.println("\ntype="+type+"\n");
return new FileTypeDescriptor(type);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -