📄 jmfmediamanager.java
字号:
/**
* $Revision: $
* $Date: $
*
* Copyright (C) 2007 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Lesser Public License (LGPL),
* a copy of which is included in this distribution.
*/
package net.java.sipmack.media;
import org.jivesoftware.sparkimpl.plugin.phone.JMFInit;
import org.jivesoftware.Spark;
import javax.sdp.*;
import javax.media.format.AudioFormat;
import javax.media.format.VideoFormat;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.Hashtable;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.net.Inet6Address;
import net.java.sipmack.common.Log;
import net.java.sipmack.sip.NetworkAddressManager;
import net.java.sipmack.sip.SIPConfig;
import net.java.sipmack.sip.Call;
/**
* JmfMediaManager using JMF based API.
* It supports GSM, G711 and G723 codecs.
* <i>This API only currently works on windows and Mac.</i>
*
* @author Thiago Camargo
*/
public class JmfMediaManager {
private List<AudioFormat> audioFormats = new ArrayList<AudioFormat>();
protected SdpFactory sdpFactory = SdpFactory.getInstance();
/**
* Creates a Media Manager instance
*/
public JmfMediaManager() {
setupAudioFormats();
}
/**
* Returns a new jingleMediaSession
*
* @param audioFormat
* @param remote
* @param local
* @return
*/
public AudioMediaSession createMediaSession(final AudioFormat audioFormat, final TransportCandidate remote, final TransportCandidate local) {
String locator = "javasound://";
if (Spark.isWindows()) {
locator = "dsound://";
}
return new AudioMediaSession(audioFormat, remote, local, locator);
}
/**
* Setup API supported AudioFormats
*/
private void setupAudioFormats() {
audioFormats.add(new AudioFormat(AudioFormat.GSM_RTP));
audioFormats.add(new AudioFormat(AudioFormat.G723_RTP));
audioFormats.add(new AudioFormat(AudioFormat.ULAW_RTP));
}
/**
* Return all supported Payloads for this Manager
*
* @return The Payload List
*/
public List<AudioFormat> getAudioFormats() {
return audioFormats;
}
/**
* Creates a new AudioMedia Session for a given sdpData
*
* @param sdpData
* @return
* @throws MediaException
*/
public AudioMediaSession createAudioMediaSession(String sdpData, int localPort) throws MediaException {
String locator = "javasound://";
if (Spark.isWindows()) {
locator = "dsound://";
}
SessionDescription sessionDescription = null;
if (sdpData == null) {
throw new MediaException("The SDP data was null! Cannot open "
+ "a stream withour an SDP Description!");
}
try {
sessionDescription = sdpFactory
.createSessionDescription(sdpData);
}
catch (SdpParseException ex) {
throw new MediaException("Incorrect SDP data!", ex);
}
Vector mediaDescriptions;
try {
mediaDescriptions = sessionDescription
.getMediaDescriptions(true);
}
catch (SdpException ex) {
throw new MediaException(
"Failed to extract media descriptions from provided session description!",
ex);
}
Connection sessionConnection = sessionDescription.getConnection();
String sessionRemoteAddress = null;
if (sessionConnection != null) {
try {
sessionRemoteAddress = sessionConnection.getAddress();
}
catch (SdpParseException ex) {
throw new MediaException(
"Failed to extract the connection address parameter"
+ "from privided session description", ex);
}
}
int mediaPort = -1;
boolean atLeastOneTransmitterStarted = false;
ArrayList mediaTypes = new ArrayList();
ArrayList remoteAddresses = new ArrayList();
// A hashtable that indicates what addresses are different media
// types
// coming from.
Hashtable remoteTransmisionDetails = new Hashtable();
// by default everything is supposed to be coming from the address
// specified in the session (global) connection parameter so store
// this address for now.
if (sessionRemoteAddress != null) {
remoteTransmisionDetails.put("audio", sessionRemoteAddress);
remoteTransmisionDetails.put("video", sessionRemoteAddress);
}
ArrayList ports = new ArrayList();
ArrayList formatSets = new ArrayList();
ArrayList contents = new ArrayList();
ArrayList localPorts = new ArrayList();
for (int i = 0; i < mediaDescriptions.size(); i++) {
MediaDescription mediaDescription = (MediaDescription) mediaDescriptions
.get(i);
Media media = mediaDescription.getMedia();
// Media Type
String mediaType = null;
try {
mediaType = media.getMediaType();
}
catch (SdpParseException ex) {
continue;
}
// Find ports
try {
mediaPort = media.getMediaPort();
}
catch (SdpParseException ex) {
throw (new MediaException(
"Failed to extract port for media type ["
+ mediaType + "]. Ignoring description!",
ex));
}
// Find formats
Vector sdpFormats = null;
try {
sdpFormats = media.getMediaFormats(true);
}
catch (SdpParseException ex) {
throw (new MediaException(
"Failed to extract media formats for media type ["
+ mediaType + "]. Ignoring description!",
ex));
}
Connection mediaConnection = mediaDescription.getConnection();
String mediaRemoteAddress = null;
if (mediaConnection == null) {
if (sessionConnection == null) {
throw new MediaException(
"A connection parameter was not present in provided session/media description");
} else {
mediaRemoteAddress = sessionRemoteAddress;
}
} else {
try {
mediaRemoteAddress = mediaConnection.getAddress();
}
catch (SdpParseException ex) {
throw new MediaException(
"Failed to extract the connection address parameter"
+ "from privided media description", ex);
}
}
// update the remote address for the current media type in case
// it is specific for this media (i.e. differs from the main
// connection address)
remoteTransmisionDetails.put(mediaType, mediaRemoteAddress);
// START TRANSMISSION
try {
remoteAddresses.add(mediaRemoteAddress);
ports.add(new Integer(mediaPort));
contents.add(mediaType);
// Selecting local ports for NAT
if (mediaType.trim().equals("video"))
localPorts.add(new Integer(22444));
else if (mediaType.trim().equals("audio"))
localPorts.add(new Integer(localPort));
else
localPorts.add(new Integer(mediaPort));
formatSets
.add(extractTransmittableJmfFormats(sdpFormats));
}
catch (MediaException ex) {
Log.error("StartMedia", ex);
throw (new MediaException(
"Could not start a transmitter for media type ["
+ mediaType + "]\nIgnoring media ["
+ mediaType + "]!", ex));
}
atLeastOneTransmitterStarted = true;
}
if (atLeastOneTransmitterStarted) {
TransportCandidate.Fixed remote = new TransportCandidate.Fixed(remoteAddresses.get(0).toString(), (Integer) ports.get(0));
TransportCandidate.Fixed local = new TransportCandidate.Fixed(NetworkAddressManager.getLocalHost().getHostAddress(), localPort);
AudioFormat audioFormat = new AudioFormat((String) (((ArrayList) formatSets.get(0)).get(0)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -