Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ビデオ通話アプリのお話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for taminif taminif
April 22, 2017

 ビデオ通話アプリのお話

Skywayサービスを利用して、iOSでWebRTCを実装した話です。

Avatar for taminif

taminif

April 22, 2017
Tweet

More Decks by taminif

Other Decks in Programming

Transcript

  1. ֤ϒϥ΢βରԠঢ়گʢPCʣ • Google Chrome • Firefox • Opera • Edge(Creators

    UpdateͰରԠ༧ఆ) • Safari(ରԠத) ※࠷৽όʔδϣϯΛର৅
  2. SkyWay iOS SDK • αΠτ͔Βμ΢ϯϩʔυ
 or GithubͰclone
 or CocoaPodsͰΠϯετʔϧ •

    Objective-CͰॻ͔Ε͍ͯΔͷͰ
 Bridging-HeaderΛ௥Ճͯ͠ಡΈࠐΈ
  3. mediaConnection // ૬खͷϝσΟΞνϟωϧΛड͚औΔCALLBACKΛઃఆ peer?.on(SKWPeerEventEnum.PEER_EVENT_CALL, callback: {(obj) -> Void in let

    mediaConnection:SKWMediaConnection = obj as! SKWMediaConnection mediaConnection.answer(self.localMediaStream) }) ※্هҎ֎ʹ΋peer.callWithId(callId, localStream)Ͱ૬खʹͭͳ͙͜ͱ͕Ͱ͖Δ
  4. localStreamΛऔಘ // peerΠχγϟϥΠζ SKWNavigator.initialize(peer) // constraintsઃఆ let constraints:SKWMediaConstraints = SKWMediaConstraints.init()

    // ΧϝϥϞʔυઃఆ constraints.cameraMode = .CAMERA_MODE_ADJUSTABLE // ΧϝϥͷҐஔઃఆ constraints.cameraPosition = .CAMERA_POSITION_FRONT // localMediaStreamऔಘ localMediaStream = SKWNavigator.getUserMedia(constraints)
  5. remoteStreamΛऔಘ // MediaConnectionͷCALLBACKΛઃఆ mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT _STREAM, callback: {(obj) -> Void in

    self.remoteMediaStream = obj as? SKWMediaStream DispatchQueue.global(qos: .default).async { let remoteVideo:SKWVideo = self.view.viewWithTag(1002) as! SKWVideo remoteVideo.isUserInteractionEnabled = true remoteVideo.addSrc(self.remoteMediaStream, track: 0) } })
  6. ΧϝϥͱϚΠΫͷڐՄΛऔΔ • Info.plistʹઆ໌จΛ༻ҙ͢Δ • ༻ҙͨ͠จ͕σόΠεڐՄऔಘ࣌ʹදࣔ͞ΕΔ • NSCameraUsageDescription • NSMicrophoneUsageDescription •

    ΧϝϥͱϚΠΫͷڐՄΛऔΔ • AVCaptureDevice • Χϝϥ͕࢖༻ෆՄͩͱgetUserMedia͕ࣦഊ͢Δ͕ɺ
 ϚΠΫ͕࢖༻ෆՄͰ΋getUserMedia͸ࣦഊ͠ͳ͍ • ϚΠΫσόΠεͷ੾Γସ͑͸Ͱ͖ͳ͍
  7. σόΠεڐՄऔಘ let cameraStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) switch (cameraStatus) { case

    .authorized: // ࢖༻Մೳ case .restricted, .notDetermined: // ࢖༻ڐՄ AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: {(granted: Bool) in // OK or CancelͰgrantedͷBool͕มΘΔ }) break case .denied: // ࢖༻ෆՄ break }
  8. localStream͕औΕͳ͍ // peerΠχγϟϥΠζ SKWNavigator.initialize(peer) // constraintsઃఆ let constraints:SKWMediaConstraints = SKWMediaConstraints.init()

    // ΧϝϥϞʔυઃఆ constraints.cameraMode = .CAMERA_MODE_ADJUSTABLE // ΧϝϥͷҐஔઃఆ constraints.cameraPosition = .CAMERA_POSITION_FRONT // localMediaStreamऔಘ localMediaStream = SKWNavigator.getUserMedia(constraints) 4USFBNܗࣜͰऔಘ͸Ͱ͖Δ͚Ͳ ࣗ෼ͷө૾͕දࣔ͞Εͳ͔ͬͨ ౰ॳ͜ͷ෦෼ͷهड़͕ൈ͚͍ͯͨ
  9. localStream͕औΕͳ͍ // peerΠχγϟϥΠζ SKWNavigator.initialize(peer) // constraintsઃఆ let constraints:SKWMediaConstraints = SKWMediaConstraints.init()

    // ΧϝϥϞʔυઃఆ constraints.cameraMode = .CAMERA_MODE_ADJUSTABLE // ΧϝϥͷҐஔઃఆ constraints.cameraPosition = .CAMERA_POSITION_FRONT // localMediaStreamऔಘ localMediaStream = SKWNavigator.getUserMedia(constraints) ಛʹฦΓ஋΋ͳ͍ؔ਺͕ͩ هࡌ͠ͳ͍ͱ໰୊͋Γ
  10. remoteMediaStream͕өΒͳ͍ // MediaConnectionͷCALLBACKΛઃఆ mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT _STREAM, callback: {(obj) -> Void in

    self.remoteMediaStream = obj as? SKWMediaStream DispatchQueue.global(qos: .default).async { let remoteVideo:SKWVideo = self.view.viewWithTag(1002) as! SKWVideo remoteVideo.isUserInteractionEnabled = true remoteVideo.addSrc(self.remoteMediaStream, track: 0) } }) ૬ख͔ΒૹΒΕ͍ͯΔ͸ͣͷө ૾͕өΒͳ͔ͬͨ
  11. remoteMediaStream͕өΒͳ͍ // MediaConnectionͷCALLBACKΛઃఆ mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT _STREAM, callback: {(obj) -> Void in

    self.remoteMediaStream = obj as? SKWMediaStream DispatchQueue.global(qos: .default).async { let remoteVideo:SKWVideo = self.view.viewWithTag(1002) as! SKWVideo remoteVideo.isUserInteractionEnabled = true remoteVideo.addSrc(self.remoteMediaStream, track: 0) } }) ඳըॲཧ͕ඞཁʹͳΔͷͰ NBJO2VFVFͰઃఆ͢Δඞཁ͕͋ͬͨ