Add new PeerConnection APIs to the ObjC SDK

This CL adds wrappers for the following PeerConnection native
APIs to the Objective C API:
- SdpSemantics enum added to the RTCConfiguration
- RTCRtpTransceiver
- RTCPeerConnection.addTrack
- RTCPeerConnection.removeTrack
- RTCPeerConnection.addTransceiver
- RTCPeerConnection.transceivers

Bug: webrtc:8870
Change-Id: I9449df9742a59e90894712dc7749ca30b569d94b
Reviewed-on: https://webrtc-review.googlesource.com/54780
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22214}
This commit is contained in:
Steve Anton
2018-02-27 15:34:53 -08:00
committed by Commit Bot
parent ac7539e2d1
commit 8cb344acfd
12 changed files with 637 additions and 25 deletions

View File

@ -58,6 +58,12 @@ NS_ASSUME_NONNULL_BEGIN
+ (rtc::KeyType)nativeEncryptionKeyTypeForKeyType:(RTCEncryptionKeyType)keyType;
+ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics;
+ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics;
+ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics;
/**
* RTCConfiguration struct representation of this RTCConfiguration. This is
* needed to pass to the underlying C++ APIs.

View File

@ -43,6 +43,7 @@
_shouldPresumeWritableWhenFullyRelayed;
@synthesize iceCheckMinInterval = _iceCheckMinInterval;
@synthesize iceRegatherIntervalRange = _iceRegatherIntervalRange;
@synthesize sdpSemantics = _sdpSemantics;
@synthesize turnCustomizer = _turnCustomizer;
- (instancetype)init {
@ -96,35 +97,38 @@
_iceRegatherIntervalRange =
[[RTCIntervalRange alloc] initWithNativeIntervalRange:nativeIntervalRange];
}
_sdpSemantics = [[self class] sdpSemanticsForNativeSdpSemantics:config.sdp_semantics];
_turnCustomizer = config.turn_customizer;
}
return self;
}
- (NSString *)description {
static NSString *formatString = @"RTCConfiguration: "
@"{\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%@\n%@\n%d\n%d\n}\n";
static NSString *formatString =
@"RTCConfiguration: "
@"{\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%@\n%@\n%d\n%d\n}\n";
return
[NSString stringWithFormat:formatString,
_iceServers,
[[self class] stringForTransportPolicy:_iceTransportPolicy],
[[self class] stringForBundlePolicy:_bundlePolicy],
[[self class] stringForRtcpMuxPolicy:_rtcpMuxPolicy],
[[self class] stringForTcpCandidatePolicy:_tcpCandidatePolicy],
[[self class] stringForCandidateNetworkPolicy:_candidateNetworkPolicy],
[[self class] stringForContinualGatheringPolicy:_continualGatheringPolicy],
_audioJitterBufferMaxPackets,
_audioJitterBufferFastAccelerate,
_iceConnectionReceivingTimeout,
_iceBackupCandidatePairPingInterval,
_iceCandidatePoolSize,
_shouldPruneTurnPorts,
_shouldPresumeWritableWhenFullyRelayed,
_iceCheckMinInterval,
_iceRegatherIntervalRange,
_disableLinkLocalNetworks,
_maxIPv6Networks];
return [NSString
stringWithFormat:formatString,
_iceServers,
[[self class] stringForTransportPolicy:_iceTransportPolicy],
[[self class] stringForBundlePolicy:_bundlePolicy],
[[self class] stringForRtcpMuxPolicy:_rtcpMuxPolicy],
[[self class] stringForTcpCandidatePolicy:_tcpCandidatePolicy],
[[self class] stringForCandidateNetworkPolicy:_candidateNetworkPolicy],
[[self class] stringForContinualGatheringPolicy:_continualGatheringPolicy],
[[self class] stringForSdpSemantics:_sdpSemantics],
_audioJitterBufferMaxPackets,
_audioJitterBufferFastAccelerate,
_iceConnectionReceivingTimeout,
_iceBackupCandidatePairPingInterval,
_iceCandidatePoolSize,
_shouldPruneTurnPorts,
_shouldPresumeWritableWhenFullyRelayed,
_iceCheckMinInterval,
_iceRegatherIntervalRange,
_disableLinkLocalNetworks,
_maxIPv6Networks];
}
#pragma mark - Private
@ -186,6 +190,7 @@
nativeConfig->ice_regather_interval_range =
rtc::Optional<rtc::IntervalRange>(*nativeIntervalRange);
}
nativeConfig->sdp_semantics = [[self class] nativeSdpSemanticsForSdpSemantics:_sdpSemantics];
if (_turnCustomizer) {
nativeConfig->turn_customizer = _turnCustomizer;
}
@ -397,4 +402,37 @@
}
}
+ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics {
switch (sdpSemantics) {
case RTCSdpSemanticsDefault:
return webrtc::SdpSemantics::kDefault;
case RTCSdpSemanticsPlanB:
return webrtc::SdpSemantics::kPlanB;
case RTCSdpSemanticsUnifiedPlan:
return webrtc::SdpSemantics::kUnifiedPlan;
}
}
+ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics {
switch (sdpSemantics) {
case webrtc::SdpSemantics::kDefault:
return RTCSdpSemanticsDefault;
case webrtc::SdpSemantics::kPlanB:
return RTCSdpSemanticsPlanB;
case webrtc::SdpSemantics::kUnifiedPlan:
return RTCSdpSemanticsUnifiedPlan;
}
}
+ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics {
switch (sdpSemantics) {
case RTCSdpSemanticsDefault:
return @"DEFAULT";
case RTCSdpSemanticsPlanB:
return @"PLAN_B";
case RTCSdpSemanticsUnifiedPlan:
return @"UNIFIED_PLAN";
}
}
@end

View File

@ -33,6 +33,8 @@ class PeerConnectionDelegateAdapter : public PeerConnectionObserver {
void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) override;
void OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver) override;
void OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> data_channel) override;

View File

@ -17,10 +17,12 @@
#import "RTCLegacyStatsReport+Private.h"
#import "RTCMediaConstraints+Private.h"
#import "RTCMediaStream+Private.h"
#import "RTCMediaStreamTrack+Private.h"
#import "RTCPeerConnection+Native.h"
#import "RTCPeerConnectionFactory+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpSender+Private.h"
#import "RTCRtpTransceiver+Private.h"
#import "RTCSessionDescription+Private.h"
#import "WebRTC/RTCLogging.h"
@ -144,6 +146,18 @@ void PeerConnectionDelegateAdapter::OnRemoveStream(
didRemoveStream:mediaStream];
}
void PeerConnectionDelegateAdapter::OnTrack(
rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
RTCRtpTransceiver *transceiver =
[[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
RTCPeerConnection *peer_connection = peer_connection_;
if ([peer_connection.delegate
respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
[peer_connection.delegate peerConnection:peer_connection
didStartReceivingOnTransceiver:transceiver];
}
}
void PeerConnectionDelegateAdapter::OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> data_channel) {
RTCDataChannel *dataChannel =
@ -334,6 +348,65 @@ void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
[_localStreams removeObject:stream];
}
- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track
streamLabels:(NSArray<NSString *> *)streamLabels {
std::vector<std::string> nativeStreamLabels;
for (NSString *label in streamLabels) {
nativeStreamLabels.push_back([label UTF8String]);
}
webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
_peerConnection->AddTrack(track.nativeTrack, nativeStreamLabels);
if (!nativeSenderOrError.ok()) {
RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
return nil;
}
return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
}
- (BOOL)removeTrack:(RTCRtpSender *)sender {
bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
if (!result) {
RTCLogError(@"Failed to remote track %@", sender);
}
return result;
}
- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
}
- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
init:(RTCRtpTransceiverInit *)init {
webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
_peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
if (!nativeTransceiverOrError.ok()) {
RTCLogError(
@"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
return nil;
}
return
[[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
}
- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
}
- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
init:(RTCRtpTransceiverInit *)init {
webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
_peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
init.nativeInit);
if (!nativeTransceiverOrError.ok()) {
RTCLogError(@"Failed to add transceiver %@: %s",
[RTCRtpReceiver stringForMediaType:mediaType],
nativeTransceiverOrError.error().message());
return nil;
}
return
[[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
}
- (void)offerForConstraints:(RTCMediaConstraints *)constraints
completionHandler:
(void (^)(RTCSessionDescription *sessionDescription,
@ -451,6 +524,18 @@ void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
return receivers;
}
- (NSArray<RTCRtpTransceiver *> *)transceivers {
std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
_peerConnection->GetTransceivers());
NSMutableArray *transceivers = [[NSMutableArray alloc] init];
for (auto nativeTransceiver : nativeTransceivers) {
RTCRtpTransceiver *transceiver =
[[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
[transceivers addObject:transceiver];
}
return transceivers;
}
#pragma mark - Private
+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:

View File

@ -40,6 +40,10 @@ class RtpReceiverDelegateAdapter : public RtpReceiverObserverInterface {
+ (RTCRtpMediaType)mediaTypeForNativeMediaType:(cricket::MediaType)nativeMediaType;
+ (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType;
+ (NSString*)stringForMediaType:(RTCRtpMediaType)mediaType;
@end
NS_ASSUME_NONNULL_END

View File

@ -126,4 +126,26 @@ void RtpReceiverDelegateAdapter::OnFirstPacketReceived(
}
}
+ (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType {
switch (mediaType) {
case RTCRtpMediaTypeAudio:
return cricket::MEDIA_TYPE_AUDIO;
case RTCRtpMediaTypeVideo:
return cricket::MEDIA_TYPE_VIDEO;
case RTCRtpMediaTypeData:
return cricket::MEDIA_TYPE_DATA;
}
}
+ (NSString *)stringForMediaType:(RTCRtpMediaType)mediaType {
switch (mediaType) {
case RTCRtpMediaTypeAudio:
return @"AUDIO";
case RTCRtpMediaTypeVideo:
return @"VIDEO";
case RTCRtpMediaTypeData:
return @"DATA";
}
}
@end

View File

@ -0,0 +1,41 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "WebRTC/RTCRtpTransceiver.h"
#include "api/rtptransceiverinterface.h"
NS_ASSUME_NONNULL_BEGIN
@interface RTCRtpTransceiverInit ()
@property(nonatomic, readonly) webrtc::RtpTransceiverInit nativeInit;
@end
@interface RTCRtpTransceiver ()
@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::RtpTransceiverInterface>
nativeRtpTransceiver;
/** Initialize an RTCRtpTransceiver with a native RtpTransceiverInterface. */
- (instancetype)initWithNativeRtpTransceiver:
(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver
NS_DESIGNATED_INITIALIZER;
+ (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection:
(RTCRtpTransceiverDirection)direction;
+ (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection:
(webrtc::RtpTransceiverDirection)nativeDirection;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,163 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "RTCRtpTransceiver+Private.h"
#import "NSString+StdString.h"
#import "RTCRtpEncodingParameters+Private.h"
#import "RTCRtpParameters+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpSender+Private.h"
#import "WebRTC/RTCLogging.h"
@implementation RTCRtpTransceiverInit
@synthesize direction = _direction;
@synthesize streamLabels = _streamLabels;
@synthesize sendEncodings = _sendEncodings;
- (instancetype)init {
if (self = [super init]) {
_direction = RTCRtpTransceiverDirectionSendRecv;
}
return self;
}
- (webrtc::RtpTransceiverInit)nativeInit {
webrtc::RtpTransceiverInit init;
init.direction = [RTCRtpTransceiver nativeRtpTransceiverDirectionFromDirection:_direction];
for (NSString *streamLabel in _streamLabels) {
init.stream_labels.push_back([streamLabel UTF8String]);
}
for (RTCRtpEncodingParameters *sendEncoding in _sendEncodings) {
init.send_encodings.push_back(sendEncoding.nativeParameters);
}
return init;
}
@end
@implementation RTCRtpTransceiver {
rtc::scoped_refptr<webrtc::RtpTransceiverInterface> _nativeRtpTransceiver;
}
- (RTCRtpMediaType)mediaType {
return [RTCRtpReceiver mediaTypeForNativeMediaType:_nativeRtpTransceiver->media_type()];
}
- (NSString *)mid {
if (_nativeRtpTransceiver->mid()) {
return [NSString stringForStdString:*_nativeRtpTransceiver->mid()];
} else {
return nil;
}
}
@synthesize sender = _sender;
@synthesize receiver = _receiver;
- (BOOL)isStopped {
return _nativeRtpTransceiver->stopped();
}
- (RTCRtpTransceiverDirection)direction {
return [RTCRtpTransceiver
rtpTransceiverDirectionFromNativeDirection:_nativeRtpTransceiver->direction()];
}
- (void)setDirection:(RTCRtpTransceiverDirection)direction {
_nativeRtpTransceiver->SetDirection(
[RTCRtpTransceiver nativeRtpTransceiverDirectionFromDirection:direction]);
}
- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut {
if (_nativeRtpTransceiver->current_direction()) {
*currentDirectionOut = [RTCRtpTransceiver
rtpTransceiverDirectionFromNativeDirection:*_nativeRtpTransceiver->current_direction()];
return YES;
} else {
return NO;
}
}
- (void)stop {
_nativeRtpTransceiver->Stop();
}
- (NSString *)description {
return [NSString
stringWithFormat:@"RTCRtpTransceiver {\n sender: %@\n receiver: %@\n}", _sender, _receiver];
}
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (object == nil) {
return NO;
}
if (![object isMemberOfClass:[self class]]) {
return NO;
}
RTCRtpTransceiver *transceiver = (RTCRtpTransceiver *)object;
return _nativeRtpTransceiver == transceiver.nativeRtpTransceiver;
}
- (NSUInteger)hash {
return (NSUInteger)_nativeRtpTransceiver.get();
}
#pragma mark - Private
- (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
return _nativeRtpTransceiver;
}
- (instancetype)initWithNativeRtpTransceiver:
(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
NSParameterAssert(nativeRtpTransceiver);
if (self = [super init]) {
_nativeRtpTransceiver = nativeRtpTransceiver;
_sender = [[RTCRtpSender alloc] initWithNativeRtpSender:nativeRtpTransceiver->sender()];
_receiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeRtpTransceiver->receiver()];
RTCLogInfo(@"RTCRtpTransceiver(%p): created transceiver: %@", self, self.description);
}
return self;
}
+ (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection:
(RTCRtpTransceiverDirection)direction {
switch (direction) {
case RTCRtpTransceiverDirectionSendRecv:
return webrtc::RtpTransceiverDirection::kSendRecv;
case RTCRtpTransceiverDirectionSendOnly:
return webrtc::RtpTransceiverDirection::kSendOnly;
case RTCRtpTransceiverDirectionRecvOnly:
return webrtc::RtpTransceiverDirection::kRecvOnly;
case RTCRtpTransceiverDirectionInactive:
return webrtc::RtpTransceiverDirection::kInactive;
}
}
+ (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection:
(webrtc::RtpTransceiverDirection)nativeDirection {
switch (nativeDirection) {
case webrtc::RtpTransceiverDirection::kSendRecv:
return RTCRtpTransceiverDirectionSendRecv;
case webrtc::RtpTransceiverDirection::kSendOnly:
return RTCRtpTransceiverDirectionSendOnly;
case webrtc::RtpTransceiverDirection::kRecvOnly:
return RTCRtpTransceiverDirectionRecvOnly;
case webrtc::RtpTransceiverDirection::kInactive:
return RTCRtpTransceiverDirectionInactive;
}
}
@end

View File

@ -63,6 +63,13 @@ typedef NS_ENUM(NSInteger, RTCEncryptionKeyType) {
RTCEncryptionKeyTypeECDSA,
};
/** Represents the chosen SDP semantics for the RTCPeerConnection. */
typedef NS_ENUM(NSInteger, RTCSdpSemantics) {
RTCSdpSemanticsDefault,
RTCSdpSemanticsPlanB,
RTCSdpSemanticsUnifiedPlan,
};
NS_ASSUME_NONNULL_BEGIN
RTC_EXPORT
@ -132,6 +139,33 @@ RTC_EXPORT
*/
@property(nonatomic, strong, nullable) RTCIntervalRange *iceRegatherIntervalRange;
/** Configure the SDP semantics used by this PeerConnection. Note that the
* WebRTC 1.0 specification requires UnifiedPlan semantics. The
* RTCRtpTransceiver API is only available with UnifiedPlan semantics.
*
* PlanB will cause RTCPeerConnection to create offers and answers with at
* most one audio and one video m= section with multiple RTCRtpSenders and
* RTCRtpReceivers specified as multiple a=ssrc lines within the section. This
* will also cause RTCPeerConnection to ignore all but the first m= section of
* the same media type.
*
* UnifiedPlan will cause RTCPeerConnection to create offers and answers with
* multiple m= sections where each m= section maps to one RTCRtpSender and one
* RTCRtpReceiver (an RTCRtpTransceiver), either both audio or both video. This
* will also cause RTCPeerConnection to ignore all but the first a=ssrc lines
* that form a Plan B stream.
*
* For users who only send at most one audio and one video track, this
* choice does not matter and should be left as Default.
*
* For users who wish to send multiple audio/video streams and need to stay
* interoperable with legacy WebRTC implementations, specify PlanB.
*
* For users who wish to send multiple audio/video streams and/or wish to
* use the new RTCRtpTransceiver API, specify UnifiedPlan.
*/
@property(nonatomic, assign) RTCSdpSemantics sdpSemantics;
- (instancetype)init;
@end

View File

@ -22,9 +22,13 @@
@class RTCPeerConnectionFactory;
@class RTCRtpReceiver;
@class RTCRtpSender;
@class RTCRtpTransceiver;
@class RTCRtpTransceiverInit;
@class RTCSessionDescription;
@class RTCLegacyStatsReport;
typedef NS_ENUM(NSInteger, RTCRtpMediaType);
NS_ASSUME_NONNULL_BEGIN
extern NSString * const kRTCPeerConnectionErrorDomain;
@ -79,7 +83,9 @@ RTC_EXPORT
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didAddStream:(RTCMediaStream *)stream;
/** Called when a remote peer closes a stream. */
/** Called when a remote peer closes a stream.
* This is not called when RTCSdpSemanticsUnifiedPlan is specified.
*/
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didRemoveStream:(RTCMediaStream *)stream;
@ -106,6 +112,14 @@ RTC_EXPORT
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didOpenDataChannel:(RTCDataChannel *)dataChannel;
/** Called when signaling indicates a transceiver will be receiving media from
* the remote endpoint.
* This is only called with RTCSdpSemanticsUnifiedPlan specified.
*/
@optional
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didStartReceivingOnTransceiver:(RTCRtpTransceiver *)transceiver;
@end
RTC_EXPORT
@ -115,6 +129,9 @@ RTC_EXPORT
* streams being added or removed.
*/
@property(nonatomic, weak, nullable) id<RTCPeerConnectionDelegate> delegate;
/** This property is not available with RTCSdpSemanticsUnifiedPlan. Please use
* |senders| instead.
*/
@property(nonatomic, readonly) NSArray<RTCMediaStream *> *localStreams;
@property(nonatomic, readonly, nullable)
RTCSessionDescription *localDescription;
@ -137,6 +154,14 @@ RTC_EXPORT
*/
@property(nonatomic, readonly) NSArray<RTCRtpReceiver *> *receivers;
/** Gets all RTCRtpTransceivers associated with this peer connection.
* Note: reading this property returns different instances of
* RTCRtpTransceiver. Use isEqual: instead of == to compare RTCRtpTransceiver
* instances.
* This is only available with RTCSdpSemanticsUnifiedPlan specified.
*/
@property(nonatomic, readonly) NSArray<RTCRtpTransceiver *> *transceivers;
- (instancetype)init NS_UNAVAILABLE;
/** Sets the PeerConnection's global configuration to |configuration|.
@ -156,12 +181,70 @@ RTC_EXPORT
/** Remove a group of remote candidates from the ICE Agent. */
- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)candidates;
/** Add a new media stream to be sent on this peer connection. */
/** Add a new media stream to be sent on this peer connection.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* addTrack instead.
*/
- (void)addStream:(RTCMediaStream *)stream;
/** Remove the given media stream from this peer connection. */
/** Remove the given media stream from this peer connection.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* removeTrack instead.
*/
- (void)removeStream:(RTCMediaStream *)stream;
/** Add a new media stream track to be sent on this peer connection, and return
* the newly created RTCRtpSender. The RTCRtpSender will be associated with
* the streams specified in the |streamLabels| list.
*
* Errors: If an error occurs, returns nil. An error can occur if:
* - A sender already exists for the track.
* - The peer connection is closed.
*/
- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track
streamLabels:(NSArray<NSString *> *)streamLabels;
/** With PlanB semantics, removes an RTCRtpSender from this peer connection.
*
* With UnifiedPlan semantics, sets sender's track to null and removes the
* send component from the associated RTCRtpTransceiver's direction.
*
* Returns YES on success.
*/
- (BOOL)removeTrack:(RTCRtpSender *)sender;
/** addTransceiver creates a new RTCRtpTransceiver and adds it to the set of
* transceivers. Adding a transceiver will cause future calls to CreateOffer
* to add a media description for the corresponding transceiver.
*
* The initial value of |mid| in the returned transceiver is nil. Setting a
* new session description may change it to a non-nil value.
*
* https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
*
* Optionally, an RtpTransceiverInit structure can be specified to configure
* the transceiver from construction. If not specified, the transceiver will
* default to having a direction of kSendRecv and not be part of any streams.
*
* These methods are only available when Unified Plan is enabled (see
* RTCConfiguration).
*/
/** Adds a transceiver with a sender set to transmit the given track. The kind
* of the transceiver (and sender/receiver) will be derived from the kind of
* the track.
*/
- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track;
- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
init:(RTCRtpTransceiverInit *)init;
/** Adds a transceiver with the given kind. Can either be RTCRtpMediaTypeAudio
* or RTCRtpMediaTypeVideo.
*/
- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType;
- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
init:(RTCRtpTransceiverInit *)init;
/** Generate an SDP offer. */
- (void)offerForConstraints:(RTCMediaConstraints *)constraints
completionHandler:(nullable void (^)
@ -204,6 +287,8 @@ RTC_EXPORT
/** Create an RTCRtpSender with the specified kind and media stream ID.
* See RTCMediaStreamTrack.h for available kinds.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* addTransceiver instead.
*/
- (RTCRtpSender *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId;

View File

@ -0,0 +1,128 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCRtpReceiver.h>
#import <WebRTC/RTCRtpSender.h>
NS_ASSUME_NONNULL_BEGIN
/** https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverdirection */
typedef NS_ENUM(NSInteger, RTCRtpTransceiverDirection) {
RTCRtpTransceiverDirectionSendRecv,
RTCRtpTransceiverDirectionSendOnly,
RTCRtpTransceiverDirectionRecvOnly,
RTCRtpTransceiverDirectionInactive,
};
/** Structure for initializing an RTCRtpTransceiver in a call to
* RTCPeerConnection.addTransceiver.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit
*/
@interface RTCRtpTransceiverInit : NSObject
/** Direction of the RTCRtpTransceiver. See RTCRtpTransceiver.direction. */
@property(nonatomic) RTCRtpTransceiverDirection direction;
/** The added RTCRtpTransceiver will be added to these streams. */
@property(nonatomic) NSArray<NSString *> *streamLabels;
/** TODO(bugs.webrtc.org/7600): Not implemented. */
@property(nonatomic) NSArray<RTCRtpEncodingParameters *> *sendEncodings;
@end
@class RTCRtpTransceiver;
/** The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the WebRTC
* specification. A transceiver represents a combination of an RTCRtpSender
* and an RTCRtpReceiver that share a common mid. As defined in JSEP, an
* RTCRtpTransceiver is said to be associated with a media description if its
* mid property is non-nil; otherwise, it is said to be disassociated.
* JSEP: https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24
*
* Note that RTCRtpTransceivers are only supported when using
* RTCPeerConnection with Unified Plan SDP.
*
* WebRTC specification for RTCRtpTransceiver, the JavaScript analog:
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver
*/
RTC_EXPORT
@protocol RTCRtpTransceiver <NSObject>
/** Media type of the transceiver. The sender and receiver will also have this
* type.
*/
@property(nonatomic, readonly) RTCRtpMediaType mediaType;
/** The mid attribute is the mid negotiated and present in the local and
* remote descriptions. Before negotiation is complete, the mid value may be
* nil. After rollbacks, the value may change from a non-nil value to nil.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
*/
@property(nonatomic, readonly) NSString *mid;
/** The sender attribute exposes the RTCRtpSender corresponding to the RTP
* media that may be sent with the transceiver's mid. The sender is always
* present, regardless of the direction of media.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender
*/
@property(nonatomic, readonly) RTCRtpSender *sender;
/** The receiver attribute exposes the RTCRtpReceiver corresponding to the RTP
* media that may be received with the transceiver's mid. The receiver is
* always present, regardless of the direction of media.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver
*/
@property(nonatomic, readonly) RTCRtpReceiver *receiver;
/** The isStopped attribute indicates that the sender of this transceiver will
* no longer send, and that the receiver will no longer receive. It is true if
* either stop has been called or if setting the local or remote description
* has caused the RTCRtpTransceiver to be stopped.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped
*/
@property(nonatomic, readonly) BOOL isStopped;
/** The direction attribute indicates the preferred direction of this
* transceiver, which will be used in calls to createOffer and createAnswer.
* An update of directionality does not take effect immediately. Instead,
* future calls to createOffer and createAnswer mark the corresponding media
* descriptions as sendrecv, sendonly, recvonly, or inactive.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
*/
@property(nonatomic) RTCRtpTransceiverDirection direction;
/** The currentDirection attribute indicates the current direction negotiated
* for this transceiver. If this transceiver has never been represented in an
* offer/answer exchange, or if the transceiver is stopped, the value is not
* present and this method returns NO.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
*/
- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut;
/** The stop method irreversibly stops the RTCRtpTransceiver. The sender of
* this transceiver will no longer send, the receiver will no longer receive.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
*/
- (void)stop;
@end
RTC_EXPORT
@interface RTCRtpTransceiver : NSObject <RTCRtpTransceiver>
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END