Mediasoup-Client-Swift 0.7.0

Mediasoup-Client-Swift 0.7.0

Alexander GorbunovRoman Kuzakov 维护。



  • 作者
  • Alexander Gorbunov

CocoaPods CocoaPods

Mediasoup-Client-Swift

适用于 iOS 的 libmediasoupclient 的 Swift 封装

主要特性

  1. 一流 Swift 支持

    • 不会因未处理的 C++ 异常而崩溃。每个抛出 C++ 函数都进行了适当的包装并抛出一个可捕获的 Swift.Error

    • 公开接口中没有隐式未解包的可选。所有不安全操作都隐藏在包装器内部。

    • 公开接口中没有 Objective-C 实体。您需要的一切都封装到普通的 Swift 实体和协议中。不需要在您的代理中继承 NSObject,没有任何神秘的 NSErrors,几乎没有任何神秘的 NSStringNSInteger 基础 "枚举"。

  2. 易于集成

    如果您不需要自定义 Mediasoup-Client-Swift 本身或其依赖项,只需将一行代码添加到 Podfile 中。

    pod 'Mediasoup-Client-Swift', '0.4.2'
  3. 从头开始构建的便利性

    所有依赖项(WebRTC、libmediasoupclient、libsdptransform)都是预构建的,并添加到存储库中作为 .xcframework 的二进制文件,以减少应用程序构建时间。从头开始抓取和构建它们需要几个小时。如果您出于安全策略不允许导入二进制依赖项,或者您只想深入了解,您可以在您的计算机上构建一切。

    使用单一命令解决依赖项:.\build.sh。WebRTC 源代码是从官方仓库获取的,然后在本地进行补丁处理,使其能够在 iOS 平台上使用,并暴露一些缺失功能。如果您想切换到另一个 WebRTC 版本,配置 WebRTC 编译器标志或进行其他自定义,请深入了解 build.sh。我们使用 XCFrameworks 来覆盖设备和中继器,包括 Apple Silicon mac 上的中继器,这是不可能通过较旧的 .framework 格式实现的。

  4. 开箱即用的编解码器支持

    • 在支持的 iOS 设备上硬件加速 H264。

    • VP8 编码解码软件。

    • 其他编解码器可以轻松添加(查看 DeviceWrapper 初始化)。

  5. TURN 服务器支持

    我们对 libmediasoupclient 进行了修补,以支持当通过 UpdateIceServers 方法传递时,RTCIceServers 描述的现代格式。

  6. 无内存泄露

    好的,没有 已知的 内存泄露 ;)

用法

假设您有一个 Mediasoup 服务器并且您的应用中已设置信号,以下是简化版本的客户端实现示例

import UIKit
import Mediasoup
import AVFoundation
import WebRTC

final class MediasoupClient {
    private let signaling: Signaling
    private let pcFactory = RTCPeerConnectionFactory()
    private var mediaStream: RTCMediaStream?
    private var audioTrack: RTCAudioTrack?
    private var device: Device?
    private var sendTransport: SendTransport?
    private var producer: Producer?

    init(signaling: Signaling) {
        self.signaling = signaling
    }

    func setupDevices() {
        guard AVCaptureDevice.authorizationStatus(for: .audio) == .authorized else {
            AVCaptureDevice.requestAccess(for: .audio) { _ in
            }
            return
        }

        mediaStream = pcFactory.mediaStream(withStreamId: Constants.mediaStreamId)
        let audioTrack = pcFactory.audioTrack(withTrackId: Constants.audioTrackId)
        mediaStream?.addAudioTrack(audioTrack)
        self.audioTrack = audioTrack

        let device = Device()
        self.device = device
        do {
            try device.load(with: signaling.rtpCapabilities)
            let sendTransport = try device.createSendTransport(
                id: signaling.sendTransportId,
                iceParameters: signaling.sendTransportICEParameters,
                iceCandidates: signaling.sendTransportICECandidates,
                dtlsParameters: signaling.sendTransportDTLSParameters,
                sctpParameters: nil,
                appData: nil
            )
            sendTransport.delegate = self
            self.sendTransport = sendTransport

            let producer = try sendTransport.createProducer(
                for: audioTrack,
                encodings: nil,
                codecOptions: nil,
                appData: nil
            )
            self.producer = producer
            producer.delegate = self
            producer.resume()
        } catch let error as MediasoupError {
            // Handle errors.
        } catch {
            // Handle errors.
        }
    }
}

extension MediasoupClient: SendTransportDelegate {
    func onProduce(transport: Transport, kind: MediaKind, rtpParameters: String, appData: String, callback: @escaping (String?) -> Void) {
        // Handle state changes.
    }

    func onProduceData(transport: Transport, sctpParameters: String, label: String, protocol dataProtocol: String, appData: String, callback: @escaping (String?) -> Void) {
        // Handle state changes.
    }

    func onConnect(transport: Transport, dtlsParameters: String) {
        // Handle state changes.
    }

    func onConnectionStateChange(transport: Transport, connectionState: TransportConnectionState) {
        
        // Handle state changes.
    }
}

extension MediasoupClient: ProducerDelegate {
    func onTransportClose(in producer: Producer) {
        // Handle state changes.
    }
}

依赖关系

Mediasoup-Client-Swift 几乎没有逻辑,它只是其他优秀库的便捷包装器。

路线图

  • 升级 WebRTC 和 libmediasoupclient 到最新版本

  • 添加数据通道支持(消费)

  • 支持通过 SPM 集成

  • 为 Mediasoup-Client-Swift 的公共接口添加文档

  • 调查并减少 WebRTC 补丁的数量

  • 使依赖关系构建脚本更加灵活:为包含的编解码器和其他 WebRTC 模块添加参数化,构建架构等

  • 添加数据通道支持(生产)

  • 实现与 https://v3demo.mediasoup.org 兼容的示例应用