Skip to content

Commit 93b3edc

Browse files
authored
Merge pull request #16 from OpenTelecom/twilio-support
Prevent override mediaDevices on iOS 14.3
2 parents 77297e7 + 7dbe746 commit 93b3edc

10 files changed

Lines changed: 78 additions & 47 deletions

WKWebViewRTC/Classes/WKWebViewRTC.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class WKWebViewRTC : NSObject {
5050

5151
if let path = Bundle(for: type(of: self)).path(forResource: "jsWKWebViewRTC", ofType: "js") {
5252
if let bindingJS = try? String(contentsOfFile: path, encoding: .utf8) {
53-
let script = WKUserScript(source: bindingJS, injectionTime: .atDocumentStart, forMainFrameOnly: true)
53+
let script = WKUserScript(source: bindingJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
5454
contentController?.addUserScript(script)
5555
}
5656
}

WKWebViewRTC/Classes/iGetUserMedia.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ class iGetUserMedia {
140140
return
141141
}
142142

143+
if let device = rtcVideoTrack!.videoCaptureController?.device {
144+
rtcVideoTrack!.capabilities["deviceId"] = device.uniqueID
145+
}
146+
143147
rtcMediaStream.addVideoTrack(rtcVideoTrack!)
144148
}
145149

WKWebViewRTC/Classes/iMediaStream.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class iMediaStream : NSObject {
3131
if (streamId == nil) {
3232
// Handle possible duplicate remote trackId with janus or short duplicate name
3333
// See: https://github.com/cordova-rtc/cordova-plugin-iosrtc/issues/432
34-
// if (rtcMediaStream.streamId.count < 36) {
34+
if (rtcMediaStream.streamId.count < 36) {
3535
self.id = rtcMediaStream.streamId + "_" + UUID().uuidString;
36-
// } else {
37-
// self.id = rtcMediaStream.streamId;
38-
// }
36+
} else {
37+
self.id = rtcMediaStream.streamId;
38+
}
3939
} else {
4040
self.id = streamId!;
4141
}

WKWebViewRTC/Classes/iMediaStreamTrack.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class iMediaStreamTrack : NSObject {
2727
if (trackId == nil) {
2828
// Handle possible duplicate remote trackId with janus or short duplicate name
2929
// See: https://github.com/cordova-rtc/cordova-plugin-iosrtc/issues/432
30-
// if (rtcMediaStreamTrack.trackId.count<36) {
30+
if (rtcMediaStreamTrack.trackId.count<36) {
3131
self.id = rtcMediaStreamTrack.trackId + "_" + UUID().uuidString;
32-
// } else {
33-
// self.id = rtcMediaStreamTrack.trackId;
34-
// }
32+
} else {
33+
self.id = rtcMediaStreamTrack.trackId;
34+
}
3535
} else {
3636
self.id = trackId!;
3737
}
@@ -66,6 +66,7 @@ class iMediaStreamTrack : NSObject {
6666
"kind": self.kind,
6767
"trackId": self.rtcMediaStreamTrack.trackId,
6868
"enabled": self.rtcMediaStreamTrack.isEnabled ? true : false,
69+
"capabilities": self.rtcMediaStreamTrack.capabilities,
6970
"readyState": self.getReadyState()
7071
]
7172
}

WKWebViewRTC/Classes/iRTCAudioController.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,12 @@ class iRTCAudioController {
6767
// Setter function inserted by save specific audio device
6868
static func saveInputAudioDevice(inputDeviceUID: String) -> Void {
6969
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
70-
let audioInput: [AVAudioSessionPortDescription] = audioSession.availableInputs!.filter({
71-
(value:AVAudioSessionPortDescription) -> Bool in
72-
return value.uid == inputDeviceUID
73-
})
74-
75-
if audioInput.count > 0
76-
{
77-
iRTCAudioController.audioInputSelected = audioInput[0]
78-
}
70+
if let audioInput: AVAudioSessionPortDescription = audioSession.availableInputs!.first(where: { $0.uid == inputDeviceUID }) {
71+
iRTCAudioController.audioInputSelected = audioInput
72+
} else {
73+
NSLog("iRTCAudioController#saveInputAudioDevice() | ERROR invalid deviceId \(inputDeviceUID)")
74+
iRTCAudioController.audioInputSelected = audioSession.availableInputs!.first
75+
}
7976
}
8077

8178
// Setter function inserted by set specific audio device

WKWebViewRTC/Classes/iRTCPeerConnectionConfig.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class iRTCPeerConnectionConfig {
5050

5151
let sdpSemanticsConfig = pcConfig?.object(forKey: "sdpSemantics") as? String;
5252
let sdpSemantics = (sdpSemanticsConfig != nil && allowedSdpSemantics[sdpSemanticsConfig!] != nil) ?
53-
allowedSdpSemantics[sdpSemanticsConfig!] : RTCSdpSemantics.unifiedPlan
53+
allowedSdpSemantics[sdpSemanticsConfig!] : RTCSdpSemantics.planB
5454

5555
rtcConfiguration.sdpSemantics = sdpSemantics!;
5656

WKWebViewRTC/Classes/iRTCVideoCaptureController.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extension RTCMediaStreamTrack {
3434

3535
class PropClass {
3636
var videoCaptureController: iRTCVideoCaptureController?
37+
let capabilities = NSMutableDictionary()
3738
}
3839

3940
var _propClass : PropClass {
@@ -51,6 +52,12 @@ extension RTCMediaStreamTrack {
5152
_propClass.videoCaptureController = newValue
5253
}
5354
}
55+
56+
var capabilities: NSMutableDictionary {
57+
get {
58+
return _propClass.capabilities
59+
}
60+
}
5461
}
5562

5663
class iRTCVideoCaptureController : NSObject {

WKWebViewRTC/Js/jsWKWebViewRTC.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,6 +2407,7 @@ function MediaStreamTrack(dataFromEvent) {
24072407
this.kind = dataFromEvent.kind;
24082408
this.label = dataFromEvent.label;
24092409
this.muted = false; // TODO: No "muted" property in ObjC API.
2410+
this.capabilities = dataFromEvent.capabilities;
24102411
this.readyState = dataFromEvent.readyState;
24112412

24122413
// Private attributes.
@@ -2440,11 +2441,11 @@ Object.defineProperty(MediaStreamTrack.prototype, 'enabled', {
24402441
});
24412442

24422443
MediaStreamTrack.prototype.getConstraints = function () {
2443-
throw new Error('Not implemented.');
2444+
return {};
24442445
};
24452446

24462447
MediaStreamTrack.prototype.applyConstraints = function () {
2447-
throw new Error('Not implemented.');
2448+
return Promise.reject(new Error('applyConstraints is not implemented.'));
24482449
};
24492450

24502451
MediaStreamTrack.prototype.clone = function () {
@@ -2464,7 +2465,7 @@ MediaStreamTrack.prototype.clone = function () {
24642465
MediaStreamTrack.prototype.getCapabilities = function () {
24652466
//throw new Error('Not implemented.');
24662467
// SHAM
2467-
return new MediaTrackCapabilities();
2468+
return new MediaTrackCapabilities(this.capabilities);
24682469
};
24692470

24702471
MediaStreamTrack.prototype.getSettings = function () {
@@ -4803,12 +4804,13 @@ module.exports = {
48034804
mediaStreams: mediaStreams,
48044805
nativeCallback: exec.nativeCallback
48054806
};
4807+
4808+
// register global variables right after webview loading
48064809
registerGlobals();
4807-
initAudioDevices();
4808-
turnOnSpeaker(true);
4809-
requestPermission(true, true, function (result) {
4810-
console.log('requestPermission.result', result);
4811-
});
4810+
4811+
MediaStreamTrack.prototype.clone = function () {
4812+
return this;
4813+
};
48124814

48134815
domready(function () {
48144816
// Let the MediaStream class and the videoElementsHandler share same MediaStreams container.
@@ -4920,20 +4922,29 @@ function registerGlobals(doNotRestoreCallbacksSupport) {
49204922
global.navigator = {};
49214923
}
49224924

4923-
if (!navigator.mediaDevices) {
4924-
navigator.mediaDevices = new MediaDevices();
4925-
}
4926-
49274925
// Restore Callback support
49284926
if (!doNotRestoreCallbacksSupport) {
49294927
restoreCallbacksSupport();
49304928
}
49314929

49324930
navigator.getUserMedia = getUserMedia;
49334931
navigator.webkitGetUserMedia = getUserMedia;
4934-
navigator.mediaDevices.getUserMedia = getUserMedia;
4935-
navigator.mediaDevices.enumerateDevices = enumerateDevices;
49364932

4933+
// Prevent WebRTC-adapter to overide navigator.mediaDevices after shim is applied since ios 14.3
4934+
Object.defineProperty(
4935+
navigator,
4936+
'mediaDevices',
4937+
{
4938+
value: new MediaDevices(),
4939+
writable: false
4940+
},
4941+
{
4942+
enumerable: false,
4943+
configurable: false,
4944+
writable: false,
4945+
value: 'static'
4946+
});
4947+
49374948
window.RTCPeerConnection = RTCPeerConnection;
49384949
window.webkitRTCPeerConnection = RTCPeerConnection;
49394950
window.RTCSessionDescription = RTCSessionDescription;

WKWebViewRTC/Js/src/MediaStreamTrack.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ function MediaStreamTrack(dataFromEvent) {
5353
this.kind = dataFromEvent.kind;
5454
this.label = dataFromEvent.label;
5555
this.muted = false; // TODO: No "muted" property in ObjC API.
56+
this.capabilities = dataFromEvent.capabilities;
5657
this.readyState = dataFromEvent.readyState;
5758

5859
// Private attributes.
@@ -86,11 +87,11 @@ Object.defineProperty(MediaStreamTrack.prototype, 'enabled', {
8687
});
8788

8889
MediaStreamTrack.prototype.getConstraints = function () {
89-
throw new Error('Not implemented.');
90+
return {};
9091
};
9192

9293
MediaStreamTrack.prototype.applyConstraints = function () {
93-
throw new Error('Not implemented.');
94+
return Promise.reject(new Error('applyConstraints is not implemented.'));
9495
};
9596

9697
MediaStreamTrack.prototype.clone = function () {
@@ -110,7 +111,7 @@ MediaStreamTrack.prototype.clone = function () {
110111
MediaStreamTrack.prototype.getCapabilities = function () {
111112
//throw new Error('Not implemented.');
112113
// SHAM
113-
return new MediaTrackCapabilities();
114+
return new MediaTrackCapabilities(this.capabilities);
114115
};
115116

116117
MediaStreamTrack.prototype.getSettings = function () {

WKWebViewRTC/Js/src/iosrtc.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,13 @@ module.exports = {
8787
mediaStreams: mediaStreams,
8888
nativeCallback: exec.nativeCallback
8989
};
90+
91+
// register global variables right after webview loading
9092
registerGlobals();
91-
initAudioDevices();
92-
turnOnSpeaker(true);
93-
requestPermission(true, true, function (result) {
94-
console.log('requestPermission.result', result);
95-
});
93+
94+
MediaStreamTrack.prototype.clone = function () {
95+
return this;
96+
};
9697

9798
domready(function () {
9899
// Let the MediaStream class and the videoElementsHandler share same MediaStreams container.
@@ -204,20 +205,29 @@ function registerGlobals(doNotRestoreCallbacksSupport) {
204205
global.navigator = {};
205206
}
206207

207-
if (!navigator.mediaDevices) {
208-
navigator.mediaDevices = new MediaDevices();
209-
}
210-
211208
// Restore Callback support
212209
if (!doNotRestoreCallbacksSupport) {
213210
restoreCallbacksSupport();
214211
}
215212

216213
navigator.getUserMedia = getUserMedia;
217214
navigator.webkitGetUserMedia = getUserMedia;
218-
navigator.mediaDevices.getUserMedia = getUserMedia;
219-
navigator.mediaDevices.enumerateDevices = enumerateDevices;
220215

216+
// Prevent WebRTC-adapter to overide navigator.mediaDevices after shim is applied since ios 14.3
217+
Object.defineProperty(
218+
navigator,
219+
'mediaDevices',
220+
{
221+
value: new MediaDevices(),
222+
writable: false
223+
},
224+
{
225+
enumerable: false,
226+
configurable: false,
227+
writable: false,
228+
value: 'static'
229+
});
230+
221231
window.RTCPeerConnection = RTCPeerConnection;
222232
window.webkitRTCPeerConnection = RTCPeerConnection;
223233
window.RTCSessionDescription = RTCSessionDescription;

0 commit comments

Comments
 (0)