7

We would like to use WebRTC to send an iOS devices’ screen capture using ReplayKit. The ReplayKit has a processSampleBuffer callback which gives CMSampleBuffer.

But here is where we are stuck, we can’t seem to get the CMSampleBuffer to be sent to the connected peer. We have tried to create pixelBuffer from the sampleBuffer, and then create RTCVideoFrame.

we also extracted the RTCVideoSource from RTCPeerConnectionFactory and then used an RTCVideoCapturer and stream it to the localVideoSource.

Any idea what we are doing wrong?

var peerConnectionFactory: RTCPeerConnectionFactory?

override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
 switch sampleBufferType {
           case RPSampleBufferType.video:

        // create the CVPixelBuffer
        let pixelBuffer:CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!;

        // create the RTCVideoFrame
        var videoFrame:RTCVideoFrame?;
        let timestamp = NSDate().timeIntervalSince1970 * 1000
        videoFrame = RTCVideoFrame(pixelBuffer: pixelBuffer, rotation: RTCVideoRotation._0, timeStampNs: Int64(timestamp))

        // connect the video frames to the WebRTC
        let localVideoSource = self.peerConnectionFactory!.videoSource()
        let videoCapturer = RTCVideoCapturer()
        localVideoSource.capturer(videoCapturer, didCapture: videoFrame!)

        let videoTrack : RTCVideoTrack =   self.peerConnectionFactory!.videoTrack(with: localVideoSource, trackId: "100”)

        let mediaStream: RTCMediaStream = (self.peerConnectionFactory?.mediaStream(withStreamId: “1"))!
        mediaStream.addVideoTrack(videoTrack)
        self.newPeerConnection!.add(mediaStream)

        break
    }
}
Niro
  • 91
  • 1
  • 4

1 Answers1

5

This is a great idea to implement you just have to render the RTCVideoFrame in the method that you have used in the snippet, and all the other object will initialize outsize the method, best way. for better understanding, I am giving you a snippet.

    var peerConnectionFactory: RTCPeerConnectionFactory?
    var localVideoSource: RTCVideoSource?
    var videoCapturer: RTCVideoCapturer?
    func setupVideoCapturer(){
          // localVideoSource and videoCapturer will use 
            localVideoSource = self.peerConnectionFactory!.videoSource() 
            videoCapturer = RTCVideoCapturer()
    //      localVideoSource.capturer(videoCapturer, didCapture: videoFrame!)
    
            let videoTrack : RTCVideoTrack =   self.peerConnectionFactory!.videoTrack(with: localVideoSource, trackId: "100")
    
            let mediaStream: RTCMediaStream = (self.peerConnectionFactory?.mediaStream(withStreamId: "1"))!
            mediaStream.addVideoTrack(videoTrack)
            self.newPeerConnection!.add(mediaStream)
        }


 override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
     switch sampleBufferType {
               case RPSampleBufferType.video:
    
            // create the CVPixelBuffer
            let pixelBuffer:CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!;
    
            // create the RTCVideoFrame
            var videoFrame:RTCVideoFrame?;
            let timestamp = NSDate().timeIntervalSince1970 * 1000
            videoFrame = RTCVideoFrame(pixelBuffer: pixelBuffer, rotation: RTCVideoRotation._0, timeStampNs: Int64(timestamp))
            // connect the video frames to the WebRTC
            localVideoSource.capturer(videoCapturer, didCapture: videoFrame!)
    
            break
        }
    }

Hope this will help you.

MGY
  • 7,245
  • 5
  • 41
  • 74
Sumit Meena
  • 474
  • 3
  • 11
  • What about the audio? RTCVideoTrack is only for video samples. Can anyone help me with audio snippet? – user2801184 Jan 31 '19 at 22:16
  • I tried, but as I check we can not do it with the existing framework. we can achieve this by customizing the SDK with source code. I did it with this way. – Sumit Meena Feb 03 '19 at 18:03
  • Can you please guide me with steps?If you could just share webrtc.framework & a snippet like above for audio that would be great help! May be answer my question https://stackoverflow.com/questions/54470143/send-replay-kit-audio-samplesnot-microphone-over-webrtc – user2801184 Feb 04 '19 at 18:58
  • Hi Sumit, can you please respond with steps if possible? – user2801184 Feb 06 '19 at 00:19
  • I tried the same way but I did not receive the video on the web. Can you please share your approach @sumitmeena @replies? Many thanks – Aboulfouz Feb 09 '19 at 08:18
  • hi @Aboulfouz, you are not able to receive video in web or any remote device ?? you can check it on your local view if the video is working on local view than it will work in the remote. – Sumit Meena Feb 09 '19 at 09:26
  • HI @sumitmeena, Many thanks for answering I did not get the video on the web, The web page receives ontrack event but never shows the video :( . – Aboulfouz Feb 10 '19 at 10:30
  • Hi @user2801184 I can try but whenever I get time. – Sumit Meena Feb 10 '19 at 17:44
  • Hi @Aboulfouz can you share the snippet so that I can check it. – Sumit Meena Feb 11 '19 at 09:17
  • Hi @sumitmeena: I can work with you if you can guide me. If not I will wait for your response.@aboulfouz: If you run this https://github.com/Mobcrush/ReplayKitDemo with apprtc latest demo app from google. It did work for me. – user2801184 Feb 11 '19 at 16:55
  • sure I am looking forward for this. – Sumit Meena Feb 13 '19 at 09:02
  • Hi @sumitmeena, I used the same exact code above and to create the peerConnect self.newPeerConnection = self.peerConnectionFactory?.peerConnection(with: rtcConfig, constraints: RTCMediaConstraints(mandatoryConstraints: ["OfferToRecieveVideo":"true"], optionalConstraints: nil), delegate: self) – Aboulfouz Feb 13 '19 at 14:55
  • have you check webrtc internal in chrome ? – Sumit Meena Feb 14 '19 at 06:39
  • I added the track id with 100 but in chrome when I inspected the stream object it contains a track with auto generated id not the 100, Could this cause the problem? @sumitmeena many thanks for your time – Aboulfouz Feb 14 '19 at 07:59
  • getting these type of error when rendering above snippet to view in localView Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType width]: unrecognized selector sent to instance 0x2829c6300' – Rajesh.k Feb 20 '19 at 14:18
  • Hi @sumitmeena The problem was with the timestamp. When I changed the timestamp to let ctm = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) ctm.value. It worked but the video freezes after 10 secs :( did you encounter the same issue? – Aboulfouz Feb 25 '19 at 07:24
  • @sumitmeena@Aboulfouz.. iam getting buffers when transferring from iOS to android but not from iOS to iOS through WebRTC…..is there any problem with codec if yes how can I change the configuration ….Can you please help me out – Rajesh.k Mar 29 '19 at 06:07
  • @sumitmeena@Aboulfouz: Hey Guys I am getting error with latest webrtc libraries Can you please help and answer my question? https://stackoverflow.com/questions/61190672/unable-to-screencast-to-apprtc-using-replay-kit-over-webrtc – user2801184 Apr 13 '20 at 15:02