Как изменить (добавить фильтры) поток камеры, который WebRTC отправляет другим узлам / серверу
Объем
Я использую RTCCameraPreviewView, чтобы показать поток локальной камеры
let videoSource = self.pcFactory.avFoundationVideoSource(with: nil)
let videoTrack = self.pcFactory.videoTrack(with: sVideoSource, trackId: "video0")
//setting the capture session to my RTCCameraPreviewView:
(self.previewView as! RTCCameraPreviewView).captureSession = (videoTrack.source as! RTCAVFoundationVideoSource).captureSession
stream = self.pcFactory.mediaStream(withStreamId: "unique_label")
audioTrack = self.pcFactory.audioTrack(withTrackId: "audio0")
stream.addAudioTrack(audioTrack)
var device: AVCaptureDevice?
for captureDevice in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) {
if (captureDevice as AnyObject).position == AVCaptureDevicePosition.front {
device = captureDevice as? AVCaptureDevice
break
}
}
if device != nil && videoTrack != nil {
stream.addVideoTrack(videoTrack)
}
configuration = RTCConfiguration()
configuration.iceServers = iceServers
peerConnection = self.pcFactory.peerConnection(with: configuration, constraints: RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: ["DtlsSrtpKeyAgreement": "true"]), delegate: self)
peerConnection.add(stream)
Все работает хорошо, как и ожидалось.
проблема
Теперь я хочу взять кадры из камеры и предварительно обработать их, добавить несколько фильтров (сепия, ч / б и т. Д.), А затем передать кадры в WebRTC. Пройдя через документацию webrtc, я все еще не могу понять, с чего начать и что делать.
Любой вид хедз-ап будет высоко оценен!
1 ответ
Я нашел выход. Поэтому в основном вам нужно создать свой собственный модуль WebRTC, а затем вы можете добавить ловушку для использования пользовательского AVCaptureVideoDataOutputSampleBufferDelegate для объекта videoOutput. Затем обработайте sampleBuffer, измените буфер и затем перейдите к webrtc.
Реализация
Откройте файл webrtc/sdk/objc/Frameworks/Classes/RTCAVFoundationVideoCapturerInternal.mm
и на линии:
[videoDataOutput setSampleBufferDelegate:self queue:self.frameQueue];
используйте собственный делегат вместо себя.
В этом делегате
class YourDelegate : AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
//modify the pixelBuffer
//get the modifiedSampleBuffer from modified pixelBuffer
DispatchQueue.main.async {
//show the modified buffer to the user
}
//To pass the modified buffer to webrtc (warning: [this is objc code]):
//(_capturer object is found in RTCAVFoundationVideoCapturerInternal.mm)
_capturer->CaptureSampleBuffer(modifiedSampleBuffer, _rotation);
}
}