Importing and Exporting RTP Media Streams
Many applications need to be able to read and write RTP streams. For example, conferencing application might record a conference and broadcast it at a later time, or telephony applications might transmit stored audio streams for announcement messages or hold music.
You can save RTP streams received from the network to a file using an RTP file writer DataSink. Similarly, you can read saved files and either present them locally or transmit them across the network.
Reading RTP Media Streams from a File
To read data from a file and present or transmit it, you can use a MediaLocator that identifies the file to construct a DataSource, or use the MediaLocator to directly construct your Processor. The file types that can be used for RTP transmissions depend on what codec plug-ins you have available to transcode and packetize the data into an RTP-specific format.
Example 11-1: Reading RTP streams from a file (1 of 3)
// Create a Processor for the selected file. Exit if the
// Processor cannot be created.
try {
String url= "file:/home/foo/foo.au";
processor
= Manager.createProcessor( new MediaLocator(url));
} catch (IOException e) {
System.exit(-1);
|
} catch (NoProcessorException e) {
System.exit(-1);
}
// configure the processor
processor.configure();
// Block until the Processor has been configured
TrackControl track[] = processor.getTrackControls();
boolean encodingOk = false;
// Go through the tracks and try to program one of them to
// output ulaw data.
for (int i = 0; i < track.length; i++) {
if (!encodingOk && track[i] instanceof FormatControl) {
if (((FormatControl)track[i]).
setFormat( new AudioFormat(AudioFormat.ULAW_RTP,
8000,
8,
1)) == null) {
track[i].setEnabled(false);
}
else {
encodingOk = true;
}
}
else {
// we could not set this track to ulaw, so disable it
track[i].setEnabled(false);
}
}
// At this point, we have determined where we can send out
// ulaw data or not.
// realize the processor
if (encodingOk) {
processor.realize();
// block until realized.
// get the output datasource of the processor and exit
// if we fail
DataSource ds = null;
try {
ds = processor.getDataOutput();
} catch (NotRealizedError e) {
System.exit(-1);
}
|
// hand this datasource to manager for creating an RTP
// datasink.
// our RTP datasink will multicast the audio
try {
String url= "rtp://224.144.251.104:49150/audio/1";
MediaLocator m = new MediaLocator(url);
DataSink d = Manager.createDataSink(ds, m);
d.open();
d.start();
} catch (Exception e) {
System.exit(-1);
}
}
|
Exporting RTP Media Streams
RTP streams received from the network can be stored as well as presented. To write the data to a file, you retrieve the DataSource from the ReceiveStream and use it to create a file writing DataSink through the Manager.
If you want to transcode the data before storing it, you can use the DataSource retrieved from the ReceiveStream to construct a Processor. You then:
- Set the track formats to perform the desired encoding.
- Get the output
DataSource from the Processor.
- Construct an RTP file writer with the
DataSource.
In the following example, whenever a new stream is created in the session:
- The stream is retrieved from
NewReceiveStreamEvent.
- The
DataSource is acquired from the ReceiveStream.
- The
DataSource is passed to the Manager.createDataSink method along with a MediaLocator that identifies the file where we want to store the data.
This example handles a single track. To write a file that contains both audio and video tracks, you need to retrieve the audio and video streams from the separate session managers and create a merging DataSource that carries both of the streams. Then you hand the merged DataSource to Manager.createDataSink.
Example 11-2: Writing an RTP stream to a file
public void update(ReceiveStreamEvent event) {
// find the source session manager for this event
SessionManager source = (SessionManager)event.getSource();
// create a filewriter datasink if a new ReceiveStream
// is detected
if (event instanceof NewReceiveStreamEvent) {
String cname = "Java Media Player";
ReceiveStream stream = null;
try {
// get the ReceiveStream
stream =((NewReceiveStreamEvent)event)
.getReceiveStream();
Participant part = stream.getParticipant();
// get the ReceiveStream datasource
DataSource dsource = stream.getDataSource();
// hand this datasource over to a file datasink
MediaLocator f = new MediaLocator("file://foo.au");
Manager.createDataSink(dsource, f);
} catch (Exception e) {
System.err.println("newReceiveStreamEvent exception "
+ e.getMessage());
return;
}
}
}
|