use of org.jitsi.service.neomedia.MediaType in project jitsi by jitsi.
the class SdpUtils method createSessionUpdateDescription.
/**
* Creates and returns a new <tt>SessionDescription</tt> that is supposed to
* update our previous <tt>descToUpdate</tt> and advertise the brand new
* <tt>newMediaDescriptions</tt>. The method also respects other 3264
* policies like reusing the origin field and augmenting its version number,
* for example.
*
* @param descToUpdate the <tt>SessionDescription</tt> to update.
* @param newConnectionAddress the <tt>InetAddress</tt> to use in the new
* <tt>c=</tt> field.
* @param newMediaDescriptions the descriptions of the new streams to have
* in the updated session.
* @return a new <tt>SessionDescription</tt> that updates
* <tt>descToUpdate</tt>
* @throws OperationFailedException if the SDP creation failed
*/
public static SessionDescription createSessionUpdateDescription(SessionDescription descToUpdate, InetAddress newConnectionAddress, List<MediaDescription> newMediaDescriptions) throws OperationFailedException {
SessionDescription update = createSessionDescription(newConnectionAddress, null, newMediaDescriptions);
//RFC 3264 says we must use it in the update and only change the ver
try {
Origin o = (Origin) descToUpdate.getOrigin().clone();
long version = o.getSessionVersion();
o.setSessionVersion(version + 1);
update.setOrigin(o);
} catch (Exception e) {
// can't happen, ignore
if (logger.isInfoEnabled())
logger.info("Something very odd just happened.", e);
}
//now, RFC 3264 says all previous m= fields must be present and new ones
//added at the end. We should also disable all m= fields that are not
//present in the new version. We therefore loop through the previous m=s
//update them along the way and then add our new descs (if any).
Vector<MediaDescription> prevMedias = extractMediaDescriptions(descToUpdate);
Vector<MediaDescription> completeMediaDescList = new Vector<MediaDescription>();
//we'll be modifying the newMediaDescs list so let's make sure we don't
//cause any trouble and clone it.
newMediaDescriptions = new Vector<MediaDescription>(newMediaDescriptions);
//description. this loop also guarantees we keep the order of streams
for (MediaDescription medToUpdate : prevMedias) {
MediaDescription desc = null;
try {
MediaType type = getMediaType(medToUpdate);
desc = removeMediaDesc(newMediaDescriptions, type);
} catch (IllegalArgumentException e) {
//remote party offers a stream of a type that we don't support.
//leave desc to null so that we'll disable it and move on.
}
if (desc == null) {
//a stream that was in the old description seems to be no longer
//there in the new one. We need to create the SDP necessary to
//explicitly disable it then.
desc = createDisablingAnswer(medToUpdate);
}
completeMediaDescList.add(desc);
}
//now add whatever's left;
for (MediaDescription medToAdd : newMediaDescriptions) {
completeMediaDescList.add(medToAdd);
}
try {
update.setMediaDescriptions(completeMediaDescList);
} catch (SdpException e) {
// can't be since we just created it.
if (logger.isInfoEnabled())
logger.info("A crazy thing just happened.", e);
}
return update;
}
use of org.jitsi.service.neomedia.MediaType in project jitsi by jitsi.
the class SdpUtils method createMediaDescription.
/**
* Creates a new <tt>MediaDescription</tt> instance according to the
* specified <tt>formats</tt>, <tt>connector</tt> and <tt>direction</tt>,
* and using the <tt>dynamicPayloadTypes</tt> registry to handle dynamic
* payload type registrations. The type (e.g. audio/video) of the media
* description is determined via from the type of the first
* <tt>MediaFormat</tt> in the <tt>formats</tt> list.
*
* @param transport the profile name (RTP/SAVP or RTP/AVP)
* @param formats the list of formats that should be advertised in the newly
* created <tt>MediaDescription</tt>.
* @param connector the socket couple that will be used for the media stream
* which we are advertising with the media description created here.
* @param direction the direction of the media stream that we are describing
* here.
* @param rtpExtensions a list of <tt>RTPExtension</tt>s supported by the
* <tt>MediaDevice</tt> that we will be advertising.
* @param dynamicPayloadTypes a reference to the
* <tt>DynamicPayloadTypeRegistry</tt> that we should be using to lookup
* and register dynamic RTP mappings.
* @param rtpExtensionsRegistry a reference to the
* <tt>DynamicRTPExtensionRegistry</tt> that we should be using to lookup
* and register URN to ID mappings.
* @return the newly create SDP <tt>MediaDescription</tt>.
* @throws OperationFailedException in case we fail to get payload type
* numbers for dynamic payload types or in case our SDP generation fails for
* some other reason.
*/
public static MediaDescription createMediaDescription(String transport, List<MediaFormat> formats, StreamConnector connector, MediaDirection direction, List<RTPExtension> rtpExtensions, DynamicPayloadTypeRegistry dynamicPayloadTypes, DynamicRTPExtensionsRegistry rtpExtensionsRegistry) throws OperationFailedException {
int[] payloadTypesArray = new int[formats.size()];
Vector<Attribute> mediaAttributes = new Vector<Attribute>(2 * payloadTypesArray.length + 1);
MediaType mediaType = null;
// a=sendonly|sendrecv|recvonly|inactive
if (direction != MediaDirection.SENDRECV)
mediaAttributes.add(createDirectionAttribute(direction));
for (int i = 0; i < payloadTypesArray.length; i++) {
MediaFormat format = formats.get(i);
MediaType fmtMediaType = format.getMediaType();
// determine whether we are dealing with audio or video.
if (mediaType == null)
mediaType = fmtMediaType;
byte payloadType = format.getRTPPayloadType();
// is this a dynamic payload type.
if (payloadType == MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN) {
try {
payloadType = dynamicPayloadTypes.obtainPayloadTypeNumber(format);
} catch (IllegalStateException exception) {
//means we ran out of dynamic rtp payload types.
throw new OperationFailedException("Failed to allocate a new dynamic PT number.", OperationFailedException.INTERNAL_ERROR, exception);
}
}
// a=rtpmap:
String numChannelsStr = "";
if (format instanceof AudioMediaFormat) {
int channels = ((AudioMediaFormat) format).getChannels();
if (channels > 1)
numChannelsStr = "/" + channels;
}
Attribute rtpmap = sdpFactory.createAttribute(SdpConstants.RTPMAP, payloadType + " " + format.getEncoding() + "/" + format.getClockRateString() + numChannelsStr);
mediaAttributes.add(rtpmap);
// a=fmtp:
if (format.getFormatParameters().size() > 0) {
Attribute fmtp = sdpFactory.createAttribute("fmtp", payloadType + " " + encodeFmtp(format));
mediaAttributes.add(fmtp);
}
/* add extra attributes */
Iterator<Map.Entry<String, String>> iter = format.getAdvancedAttributes().entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, String> ntry = iter.next();
Attribute adv;
switch(ntry.getKey()) {
// RFC7587, Sect. 7 says there's no payload number for ptime
case "ptime":
case "maxptime":
adv = sdpFactory.createAttribute(ntry.getKey(), ntry.getValue());
break;
default:
adv = sdpFactory.createAttribute(ntry.getKey(), payloadType + " " + ntry.getValue());
break;
}
mediaAttributes.add(adv);
}
payloadTypesArray[i] = payloadType;
}
// rtcp: (only include it if different from the default (i.e. rtp + 1)
int rtpPort = connector.getDataSocket().getLocalPort();
int rtcpPort = connector.getControlSocket().getLocalPort();
if ((rtpPort + 1) != rtcpPort) {
Attribute rtcpAttr = sdpFactory.createAttribute(RTCP_ATTR, Integer.toString(rtcpPort));
mediaAttributes.add(rtcpAttr);
}
// extmap: attributes
if (rtpExtensions != null && rtpExtensions.size() > 0) {
for (RTPExtension extension : rtpExtensions) {
byte extID = rtpExtensionsRegistry.obtainExtensionMapping(extension);
String uri = extension.getURI().toString();
MediaDirection extDirection = extension.getDirection();
String attributes = extension.getExtensionAttributes();
//this is what our extmap value should look like:
//extmap:<value>["/"<direction>] <URI> <extensionattributes>
String attrValue = Byte.toString(extID) + ((extDirection == MediaDirection.SENDRECV) ? "" : ("/" + extDirection.toString())) + " " + uri + (attributes == null ? "" : (" " + attributes));
Attribute extMapAttr = sdpFactory.createAttribute(EXTMAP_ATTR, attrValue);
mediaAttributes.add(extMapAttr);
}
}
MediaDescription mediaDesc = null;
try {
mediaDesc = sdpFactory.createMediaDescription(mediaType.toString(), connector.getDataSocket().getLocalPort(), 1, transport, payloadTypesArray);
// add all the attributes we have created above
mediaDesc.setAttributes(mediaAttributes);
} catch (Exception cause) {
// this is very unlikely to happen but we should still re-throw
ProtocolProviderServiceSipImpl.throwOperationFailedException("Failed to create a media description", OperationFailedException.INTERNAL_ERROR, cause, logger);
}
return mediaDesc;
}
use of org.jitsi.service.neomedia.MediaType in project jitsi by jitsi.
the class CallSipImpl method createCallPeerFor.
/**
* Creates a new call peer associated with <tt>containingTransaction</tt>
*
* @param containingTransaction the transaction that created the call peer.
* @param sourceProvider the provider that the containingTransaction belongs
* to.
* @return a new instance of a <tt>CallPeerSipImpl</tt> corresponding
* to the <tt>containingTransaction</tt>.
*/
private CallPeerSipImpl createCallPeerFor(Transaction containingTransaction, SipProvider sourceProvider) {
CallPeerSipImpl callPeer = new CallPeerSipImpl(containingTransaction.getDialog().getRemoteParty(), this, containingTransaction, sourceProvider) {
/**
* A place where we can handle any headers we need for requests
* and responses.
* @param message the SIP <tt>Message</tt> in which a header change
* is to be reflected
* @throws ParseException if modifying the specified SIP
* <tt>Message</tt> to reflect the header change fails
*/
protected void processExtraHeaders(javax.sip.message.Message message) throws ParseException {
super.processExtraHeaders(message);
CallSipImpl.this.processExtraHeaders(message);
}
};
addCallPeer(callPeer);
boolean incomingCall = (containingTransaction instanceof ServerTransaction);
callPeer.setState(incomingCall ? CallPeerState.INCOMING_CALL : CallPeerState.INITIATING_CALL);
// new and we also need to notify everyone of its creation.
if (getCallPeerCount() == 1) {
Map<MediaType, MediaDirection> mediaDirections = new HashMap<MediaType, MediaDirection>();
mediaDirections.put(MediaType.AUDIO, MediaDirection.INACTIVE);
mediaDirections.put(MediaType.VIDEO, MediaDirection.INACTIVE);
boolean hasZrtp = false;
boolean hasSdes = false;
//this check is not mandatory catch all to skip if a problem exists
try {
// lets check the supported media types.
// for this call
Request inviteReq = containingTransaction.getRequest();
if (inviteReq != null && inviteReq.getRawContent() != null) {
String sdpStr = SdpUtils.getContentAsString(inviteReq);
SessionDescription sesDescr = SdpUtils.parseSdpString(sdpStr);
List<MediaDescription> remoteDescriptions = SdpUtils.extractMediaDescriptions(sesDescr);
for (MediaDescription mediaDescription : remoteDescriptions) {
MediaType mediaType = SdpUtils.getMediaType(mediaDescription);
mediaDirections.put(mediaType, SdpUtils.getDirection(mediaDescription));
// hasZrtp?
if (!hasZrtp) {
hasZrtp = (mediaDescription.getAttribute(SdpUtils.ZRTP_HASH_ATTR) != null);
}
// hasSdes?
if (!hasSdes) {
@SuppressWarnings("unchecked") Vector<Attribute> attrs = mediaDescription.getAttributes(true);
for (Attribute attr : attrs) {
try {
if ("crypto".equals(attr.getName())) {
hasSdes = true;
break;
}
} catch (SdpParseException spe) {
logger.error("Failed to parse SDP attribute", spe);
}
}
}
}
}
} catch (Throwable t) {
logger.warn("Error getting media types", t);
}
fireCallEvent(incomingCall ? CallEvent.CALL_RECEIVED : CallEvent.CALL_INITIATED, this, mediaDirections);
if (hasZrtp) {
callPeer.getMediaHandler().addAdvertisedEncryptionMethod(SrtpControlType.ZRTP);
}
if (hasSdes) {
callPeer.getMediaHandler().addAdvertisedEncryptionMethod(SrtpControlType.SDES);
}
}
return callPeer;
}
use of org.jitsi.service.neomedia.MediaType in project Spark by igniterealtime.
the class MediaPreferencePanel method scanDevices.
@SuppressWarnings("unchecked")
public void scanDevices() {
// Remove all Items
audioDevice.removeAllItems();
videoDevice.removeAllItems();
playbackDevice.removeAllItems();
audioSystem.removeAllItems();
vectorPlaybackDevices.removeAllElements();
vectorAudioSystem.removeAllElements();
// FMJ
System.setProperty(ConfigurationService.PNAME_SC_HOME_DIR_LOCATION, Spark.getUserHome());
System.setProperty(ConfigurationService.PNAME_SC_HOME_DIR_NAME, ".");
System.setProperty(ConfigurationService.PNAME_SC_CACHE_DIR_LOCATION, Spark.getUserHome());
System.setProperty(ConfigurationService.PNAME_SC_LOG_DIR_LOCATION, Spark.getUserHome());
LibJitsi.start();
MediaType[] mediaTypes = MediaType.values();
MediaService mediaService = LibJitsi.getMediaService();
for (MediaType mediaType : mediaTypes) {
System.err.println("================================");
System.err.println("MediaType: " + mediaType);
System.out.println(mediaService);
MediaDevice device = mediaService.getDefaultDevice(mediaType, MediaUseCase.CALL);
if (device != null) {
System.out.println(device.getDirection());
}
System.err.println("Device: " + device);
System.err.println("================================");
}
vectorAudioDevices = CaptureDeviceManager.getDeviceList(new AudioFormat(AudioFormat.LINEAR));
for (CaptureDeviceInfo infoCaptureDevice : vectorAudioDevices) {
String protocol = infoCaptureDevice.getLocator().getProtocol();
audioDevice.addItem("[" + protocol + "]" + convertSysString(infoCaptureDevice.getName()));
}
vectorVideoDevices = CaptureDeviceManager.getDeviceList(new AVFrameFormat());
for (CaptureDeviceInfo infoCaptureDevice : vectorVideoDevices) {
videoDevice.addItem(convertSysString(infoCaptureDevice.getName()));
}
vectorVideoDevices.add(null);
videoDevice.addItem("<None>");
AudioSystem mediaAudioSystem = ((MediaServiceImpl) LibJitsi.getMediaService()).getDeviceConfiguration().getAudioSystem();
for (AudioSystem system : AudioSystem.getAudioSystems()) {
System.out.println(system);
vectorAudioSystem.add(system);
audioSystem.addItem(system);
}
for (CaptureDeviceInfo2 device : mediaAudioSystem.getDevices(DataFlow.PLAYBACK)) {
playbackDevice.addItem(convertSysString(device.getName()));
vectorPlaybackDevices.add(device);
}
}
use of org.jitsi.service.neomedia.MediaType in project Spark by igniterealtime.
the class AudioChannel method main.
public static void main(String[] args) {
InetAddress localhost;
try {
LibJitsi.start();
MediaType[] mediaTypes = MediaType.values();
MediaService mediaService = LibJitsi.getMediaService();
Vector<CaptureDeviceInfo> vectorAudioDevices = CaptureDeviceManager.getDeviceList(new AudioFormat(AudioFormat.LINEAR));
for (CaptureDeviceInfo infoCaptureDevice : vectorAudioDevices) {
System.out.println(infoCaptureDevice.getLocator());
}
localhost = InetAddress.getLocalHost();
byte format = 3;
AudioChannel audioChannel0 = new AudioChannel(vectorAudioDevices.get(0).getLocator(), localhost.getHostAddress(), localhost.getHostAddress(), 7002, -1, 7020, -1, MediaUtils.getMediaFormat(new AudioFormat(AudioFormat.GSM_RTP)));
AudioChannel audioChannel1 = new AudioChannel(vectorAudioDevices.get(0).getLocator(), localhost.getHostAddress(), localhost.getHostAddress(), 7020, -1, 7002, -1, MediaUtils.getMediaFormat(new AudioFormat(AudioFormat.GSM_RTP)));
audioChannel0.start();
audioChannel1.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
audioChannel0.setTrasmit(false);
audioChannel1.setTrasmit(false);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
audioChannel0.setTrasmit(true);
audioChannel1.setTrasmit(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
audioChannel0.stop();
audioChannel1.stop();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
Aggregations