Mediasoup-Client-Swift
适用于 iOS 的 libmediasoupclient 的 Swift 封装
主要特性
-
一流 Swift 支持
-
不会因未处理的 C++ 异常而崩溃。每个抛出 C++ 函数都进行了适当的包装并抛出一个可捕获的
Swift.Error
。 -
公开接口中没有隐式未解包的可选。所有不安全操作都隐藏在包装器内部。
-
公开接口中没有 Objective-C 实体。您需要的一切都封装到普通的 Swift 实体和协议中。不需要在您的代理中继承
NSObject
,没有任何神秘的NSErrors
,几乎没有任何神秘的NSString
和NSInteger
基础 "枚举"。
-
-
易于集成
如果您不需要自定义 Mediasoup-Client-Swift 本身或其依赖项,只需将一行代码添加到 Podfile 中。
pod 'Mediasoup-Client-Swift', '0.4.2'
-
从头开始构建的便利性
所有依赖项(WebRTC、libmediasoupclient、libsdptransform)都是预构建的,并添加到存储库中作为 .xcframework 的二进制文件,以减少应用程序构建时间。从头开始抓取和构建它们需要几个小时。如果您出于安全策略不允许导入二进制依赖项,或者您只想深入了解,您可以在您的计算机上构建一切。
使用单一命令解决依赖项:
.\build.sh
。WebRTC 源代码是从官方仓库获取的,然后在本地进行补丁处理,使其能够在 iOS 平台上使用,并暴露一些缺失功能。如果您想切换到另一个 WebRTC 版本,配置 WebRTC 编译器标志或进行其他自定义,请深入了解build.sh
。我们使用 XCFrameworks 来覆盖设备和中继器,包括 Apple Silicon mac 上的中继器,这是不可能通过较旧的.framework
格式实现的。 -
开箱即用的编解码器支持
-
在支持的 iOS 设备上硬件加速 H264。
-
VP8 编码解码软件。
-
其他编解码器可以轻松添加(查看
DeviceWrapper
初始化)。
-
-
TURN 服务器支持
我们对 libmediasoupclient 进行了修补,以支持当通过
UpdateIceServers
方法传递时,RTCIceServer
s 描述的现代格式。 -
无内存泄露
好的,没有 已知的 内存泄露 ;)
用法
假设您有一个 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 兼容的示例应用