<commit_before>import Foundation
import AVFoundation


class PluginGetUserMedia {
	var rtcPeerConnectionFactory: RTCPeerConnectionFactory


	init(rtcPeerConnectionFactory: RTCPeerConnectionFactory) {
		NSLog("PluginGetUserMedia#init()")

		self.rtcPeerConnectionFactory = rtcPeerConnectionFactory
	}


	func call(
		constraints: NSDictionary,
		callback: (data: NSDictionary) -> Void,
		errback: (error: String) -> Void,
		eventListenerForNewStream: (pluginMediaStream: PluginMediaStream) -> Void
	) {
		NSLog("PluginGetUserMedia#call()")

		let	audioRequested = constraints.objectForKey("audio") as? Bool ?? false
		let	videoRequested = constraints.objectForKey("video") as? Bool ?? false
		let	videoDeviceId = constraints.objectForKey("videoDeviceId") as? String

		let rtcMediaStream: RTCMediaStream = self.rtcPeerConnectionFactory.mediaStreamWithLabel(NSUUID().UUIDString)
		var pluginMediaStream: PluginMediaStream?
		var rtcAudioTrack: RTCAudioTrack?
		var rtcVideoTrack: RTCVideoTrack?
		var rtcVideoCapturer: RTCVideoCapturer?
		var rtcVideoSource: RTCVideoSource?
		var videoDevice: AVCaptureDevice?

		if videoRequested == true {
			switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) {
			case AVAuthorizationStatus.Authorized:
				NSLog("PluginGetUserMedia#call() | video authorization: authorized")
			case AVAuthorizationStatus.Denied:
				NSLog("PluginGetUserMedia#call() | video authorization: denied")
			case AVAuthorizationStatus.Restricted:
				NSLog("PluginGetUserMedia#call() | video authorization: restricted")
			case AVAuthorizationStatus.NotDetermined:
				NSLog("PluginGetUserMedia#call() | video authorization: not determined")
			}

			// No specific video device requested.
			if videoDeviceId == nil {
				NSLog("PluginGetUserMedia#call() | video requested (device not specified)")

				for device: AVCaptureDevice in (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! Array<AVCaptureDevice>) {
					if device.position == AVCaptureDevicePosition.Front {
						videoDevice = device
						break
					}
				}
			}

			// Video device specified.
			else {
				NSLog("PluginGetUserMedia#call() | video requested (specified device id: \(videoDeviceId!))")

				for device: AVCaptureDevice in (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! Array<AVCaptureDevice>) {
					if device.uniqueID == videoDeviceId {
						videoDevice = device
						break
					}
				}
			}

			if videoDevice == nil {
				NSLog("PluginGetUserMedia#call() | video requested but no suitable device found")

				errback(error: "no suitable camera device found")
				return
			}

			NSLog("PluginGetUserMedia#call() | chosen video device: \(videoDevice!)")

			rtcVideoCapturer = RTCVideoCapturer(deviceName: videoDevice!.localizedName)

			rtcVideoSource = self.rtcPeerConnectionFactory.videoSourceWithCapturer(rtcVideoCapturer,
				constraints: RTCMediaConstraints()
			)

			rtcVideoTrack = self.rtcPeerConnectionFactory.videoTrackWithID(NSUUID().UUIDString,
				source: rtcVideoSource
			)

			rtcMediaStream.addVideoTrack(rtcVideoTrack)
		}

		if audioRequested == true {
			switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeAudio) {
			case AVAuthorizationStatus.Authorized:
				NSLog("PluginGetUserMedia#call() | audio authorization: authorized")
			case AVAuthorizationStatus.Denied:
				NSLog("PluginGetUserMedia#call() | audio authorization: denied")
			case AVAuthorizationStatus.Restricted:
				NSLog("PluginGetUserMedia#call() | audio authorization: restricted")
			case AVAuthorizationStatus.NotDetermined:
				NSLog("PluginGetUserMedia#call() | audio authorization: not determined")
			}<commit_msg>Don't crash if the user or iOS settings deny audio/video permission when getUserMedia is prompted (fixes #73).<commit_after>import Foundation
import AVFoundation


class PluginGetUserMedia {
	var rtcPeerConnectionFactory: RTCPeerConnectionFactory


	init(rtcPeerConnectionFactory: RTCPeerConnectionFactory) {
		NSLog("PluginGetUserMedia#init()")

		self.rtcPeerConnectionFactory = rtcPeerConnectionFactory
	}


	func call(
		constraints: NSDictionary,
		callback: (data: NSDictionary) -> Void,
		errback: (error: String) -> Void,
		eventListenerForNewStream: (pluginMediaStream: PluginMediaStream) -> Void
	) {
		NSLog("PluginGetUserMedia#call()")

		let	audioRequested = constraints.objectForKey("audio") as? Bool ?? false
		let	videoRequested = constraints.objectForKey("video") as? Bool ?? false
		let	videoDeviceId = constraints.objectForKey("videoDeviceId") as? String

		let rtcMediaStream: RTCMediaStream = self.rtcPeerConnectionFactory.mediaStreamWithLabel(NSUUID().UUIDString)
		var pluginMediaStream: PluginMediaStream?
		var rtcAudioTrack: RTCAudioTrack?
		var rtcVideoTrack: RTCVideoTrack?
		var rtcVideoCapturer: RTCVideoCapturer?
		var rtcVideoSource: RTCVideoSource?
		var videoDevice: AVCaptureDevice?

		if videoRequested == true {
			switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) {
			case AVAuthorizationStatus.Authorized:
				NSLog("PluginGetUserMedia#call() | video authorization: authorized")
			case AVAuthorizationStatus.Denied:
				NSLog("PluginGetUserMedia#call() | video authorization: denied")
				errback(error: "video denied")
				return
			case AVAuthorizationStatus.Restricted:
				NSLog("PluginGetUserMedia#call() | video authorization: restricted")
				errback(error: "video restricted")
				return
			case AVAuthorizationStatus.NotDetermined:
				NSLog("PluginGetUserMedia#call() | video authorization: not determined")
			}

			// No specific video device requested.
			if videoDeviceId == nil {
				NSLog("PluginGetUserMedia#call() | video requested (device not specified)")

				for device: AVCaptureDevice in (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! Array<AVCaptureDevice>) {
					if device.position == AVCaptureDevicePosition.Front {
						videoDevice = device
						break
					}
				}
			}

			// Video device specified.
			else {
				NSLog("PluginGetUserMedia#call() | video requested (specified device id: \(videoDeviceId!))")

				for device: AVCaptureDevice in (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! Array<AVCaptureDevice>) {
					if device.uniqueID == videoDeviceId {
						videoDevice = device
						break
					}
				}
			}

			if videoDevice == nil {
				NSLog("PluginGetUserMedia#call() | video requested but no suitable device found")

				errback(error: "no suitable camera device found")
				return
			}

			NSLog("PluginGetUserMedia#call() | chosen video device: \(videoDevice!)")

			rtcVideoCapturer = RTCVideoCapturer(deviceName: videoDevice!.localizedName)

			rtcVideoSource = self.rtcPeerConnectionFactory.videoSourceWithCapturer(rtcVideoCapturer,
				constraints: RTCMediaConstraints()
			)

			rtcVideoTrack = self.rtcPeerConnectionFactory.videoTrackWithID(NSUUID().UUIDString,
				source: rtcVideoSource
			)

			rtcMediaStream.addVideoTrack(rtcVideoTrack)
		}

		if audioRequested == true {
			switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeAudio) {
			case AVAuthorizationStatus.Authorized:
				NSLog("PluginGetUserMedia#call() | audio authorization: authorized")
			case AVAuthorizationStatus.Denied:
				NSLog("PluginGetUserMedia#call() | audio authorization: denied")
				errback(error: "audio denied")
				return
			case AVAuthorizationStatus.Restricted:
				NSLog("PluginGetUserMedia#call() | audio authorization: restricted")
				errback(error: "audio restricted")
				return
			case AVAuthorizationStatus.NotDetermined:
				NSLog("PluginGetUserMedia#call() | audio authorization: not determined")
			}
{'fraction_non_alphanumeric': 0.09046807394781696, 'fraction_numerical': 0.0002622263012980202, 'mean_word_length': 5.156577885391445, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6932575', 'n_tokens_mistral': 2561, 'n_tokens_neox': 2138, 'n_words': 464}