Mediasoup-Client-Swift-Device 1.0.0

Mediasoup-Client-Swift-Device 1.0.0

Yoav Gross 维护。



  • 作者:
  • Yoav Gross

CocoaPods CocoaPods

Mediasoup-Client-Swift

libmediasoupclient 的 Swift 封装,支持 iOS 平台

主要特性

  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 方法时使用的现代化 RTCIceServer 描述格式。

  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兼容的示例应用