본문 바로가기

Spring Boot

[Swift] 스마트폰 카메라에서 촬영한 영상을 rtmp 송출기능

반응형
import AVFoundation
import VideoCore

class RTMPSender {
    private let session = AVCaptureSession()
    private let videoDataOutput = AVCaptureVideoDataOutput()
    private var videoPreviewLayer: AVCaptureVideoPreviewLayer!
    private var rtmpSession: VCSimpleSession!

    func startSending(to outputURL: String, on view: UIView, completion: @escaping (Result<Void, Error>) -> Void) {
        do {
            let device = AVCaptureDevice.default(for: .video)
            let input = try AVCaptureDeviceInput(device: device!)
            session.addInput(input)

            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
            videoPreviewLayer.frame = view.layer.bounds
            videoPreviewLayer.videoGravity = .resizeAspectFill
            view.layer.addSublayer(videoPreviewLayer)

            videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]
            videoDataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "video_queue"))
            session.addOutput(videoDataOutput)

            rtmpSession = try VCSimpleSession(videoSize: CGSize(width: 720, height: 1280), frameRate: 30, bitrate: 1000000, useInterfaceOrientation: false)
            rtmpSession.startRtmpSession(outputURL)
            rtmpSession.attachVideo(AVCaptureDevice.default(for: .video))
            rtmpSession.attachAudio(AVCaptureDevice.default(for: .audio))

            session.startRunning()

        } catch {
            completion(.failure(TransmissionError.sessionInitializationFailed))
        }
    }
}

extension RTMPSender: AVCaptureVideoDataOutputSampleBufferDelegate {
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
        rtmpSession.processVideoSampleBuffer(pixelBuffer)
    }
}

enum TransmissionError: Error {
    case sessionInitializationFailed
}
반응형