Mediasoup-Client-Swift
libmediasoupclient 的 Swift 封装,支持 iOS 平台
主要特性
-
一流 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
描述格式。 -
没有内存泄露
好的,没有 已知 的内存泄露 ;)
用法
假设您有一个 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兼容的示例应用