10

I have a video call app using the latest Quickblox version (Quickblox 2.5, Quickblox-WebRTC 2.0) and I need to save the video being streamed on the call a file. There is an old example with an old version of the SDK which looks nothing like the current one.

There's nothing about this on the current docs and I cannot start an AVCaptureMovieFileOutout as Quickblox is already using an AVCaptureVideoDataOutput. Is there anyway to save the stream to a file?

UPDATE:

I managed to write the video to a file. All that is missing is the audio track.

import Foundation

class VideoManager : NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {

    static let sharedInstance = VideoManager()

    var pixelBufferAdaptor: AVAssetWriterInputPixelBufferAdaptor?
    var assetWriterInput: AVAssetWriterInput?
    var assetWriter: AVAssetWriter?
    var frameNumber: Int64 = 0
    var qbDelegate: AVCaptureVideoDataOutputSampleBufferDelegate?

    func startSavingCaptureToFileWithURL(url: NSURL, capture: QBRTCCameraCapture) {
        print("[VideoManager]: startSavingCaptureToFileWithURL")
        guard let dataOutput = getVideoCaptureDataOutput(capture) else { return }

        frameNumber = 0

        qbDelegate = dataOutput.sampleBufferDelegate
        dataOutput.setSampleBufferDelegate(self, queue: dataOutput.sampleBufferCallbackQueue)

        let outputSettings: [String : AnyObject] = [
            AVVideoWidthKey : 720,
            AVVideoHeightKey: 1280,
            AVVideoCodecKey : AVVideoCodecH264
        ]

        assetWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: outputSettings)
        pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: assetWriterInput!, sourcePixelBufferAttributes: [kCVPixelBufferPixelFormatTypeKey as String : NSNumber(unsignedInt: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)])

        do {
            assetWriter = try AVAssetWriter(URL: url, fileType: AVFileTypeMPEG4)
            assetWriter!.addInput(assetWriterInput!)
            assetWriterInput!.expectsMediaDataInRealTime = true

            assetWriter!.startWriting()
            assetWriter!.startSessionAtSourceTime(kCMTimeZero)
        }
        catch {
            print("[VideoManager]: Error persisting stream!")
        }

    }

    func stopSavingVideo() {
        assetWriter?.finishWritingWithCompletionHandler { [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.frameNumber = 0
        }
    }

    private func getVideoCaptureDataOutput(videoCapture: QBRTCCameraCapture) -> AVCaptureVideoDataOutput? {
        var output: AVCaptureVideoDataOutput?
        videoCapture.captureSession.outputs.forEach{ captureOutput in
            if captureOutput is AVCaptureVideoDataOutput {
                output = captureOutput as? AVCaptureVideoDataOutput
            }
        }
        return output
    }

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
        qbDelegate?.captureOutput?(captureOutput, didOutputSampleBuffer: sampleBuffer, fromConnection: connection)

        guard let assetWriterInput = assetWriterInput else { return }
        guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

        if assetWriterInput.readyForMoreMediaData {
            pixelBufferAdaptor?.appendPixelBuffer(imageBuffer, withPresentationTime: CMTimeMake(frameNumber, 25))
        }

        frameNumber++
    }

    func getUniqueFileURL() -> NSURL {
        let guid = NSProcessInfo.processInfo().globallyUniqueString
        let fileName = "\(guid).mp4"
        return NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(fileName)
    }

}

Any ideas on how to get to QBRTCLocalAudioTrack's underlying AVCaptureAudioDataOutput?

Raphael
  • 7,972
  • 14
  • 62
  • 83

1 Answers1

0

I'm from dev QuicbkloxWebRTC team. The feature is planned for the next big release.

SevenDays
  • 3,718
  • 10
  • 44
  • 71
  • 1
    Is there no workaround for getting the audio output? My client is freaking out that the videos are being saved with no sound. – Raphael Dec 09 '15 at 21:44
  • WebRTC processes audio natively with audio frames, then WebRTC mixes audio from all opponents and only then we have ability to record audio track from mixer. Now we do investigate separate audio record. – SevenDays Dec 10 '15 at 09:13
  • @SevenDays Has this feature been implemented in the latest iOS SDK, please update. – Pranav Jaiswal Dec 29 '16 at 23:33
  • @SevenDays if this feature is available now then please let us know.? how to record audio ? – Mubin Mall Aug 03 '17 at 19:07