mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-05-07 20:12:28 +00:00
Rename Session -> StreamSesison. (#1879)
This commit is contained in:
@@ -28,9 +28,9 @@ struct HaishinApp: App {
|
||||
}
|
||||
|
||||
private func initialize() async {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
|
||||
await RTCLogger.shared.setLevel(.debug)
|
||||
await SRTLogger.shared.setLevel(.debug)
|
||||
|
||||
@@ -6,7 +6,7 @@ import SwiftUI
|
||||
|
||||
@MainActor
|
||||
final class PlaybackViewModel: ObservableObject {
|
||||
@Published private(set) var readyState: SessionReadyState = .closed
|
||||
@Published private(set) var readyState: StreamSessionReadyState = .closed
|
||||
@Published private(set) var error: Error?
|
||||
@Published var hasError = false
|
||||
|
||||
@@ -36,7 +36,7 @@ final class PlaybackViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
private var view: PiPHKView?
|
||||
private var session: (any Session)?
|
||||
private var session: (any StreamSession)?
|
||||
private let audioPlayer = AudioPlayer(audioEngine: AVAudioEngine())
|
||||
private var pictureInPictureController: AVPictureInPictureController?
|
||||
|
||||
@@ -66,7 +66,7 @@ final class PlaybackViewModel: ObservableObject {
|
||||
|
||||
func makeSession() async {
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(Preference.default.makeURL())
|
||||
session = try await StreamSessionBuilderFactory.shared.make(Preference.default.makeURL())
|
||||
.setMode(.playback)
|
||||
.build()
|
||||
await session?.setMaxRetryCount(0)
|
||||
|
||||
@@ -64,7 +64,7 @@ enum VideoEffectItem: String, CaseIterable, Identifiable, Sendable {
|
||||
}
|
||||
|
||||
struct StreamButton: View {
|
||||
let readyState: SessionReadyState
|
||||
let readyState: StreamSessionReadyState
|
||||
let onStart: () -> Void
|
||||
let onStop: () -> Void
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ final class PublishViewModel: ObservableObject {
|
||||
@Published var showPreLiveDialog = false
|
||||
@Published private(set) var isAudioMuted = false
|
||||
@Published private(set) var isTorchEnabled = false
|
||||
@Published private(set) var readyState: SessionReadyState = .closed
|
||||
@Published private(set) var readyState: StreamSessionReadyState = .closed
|
||||
@Published var audioSource: AudioSource = .empty {
|
||||
didSet {
|
||||
guard audioSource != oldValue else {
|
||||
@@ -70,7 +70,7 @@ final class PublishViewModel: ObservableObject {
|
||||
}
|
||||
private(set) var mixer = MediaMixer()
|
||||
private var tasks: [Task<Void, Swift.Error>] = []
|
||||
private var session: (any Session)?
|
||||
private var session: (any StreamSession)?
|
||||
private var recorder: StreamRecorder?
|
||||
private var currentPosition: AVCaptureDevice.Position = .back
|
||||
private var audioSourceService = AudioSourceService()
|
||||
@@ -235,7 +235,7 @@ final class PublishViewModel: ObservableObject {
|
||||
|
||||
func makeSession(_ preference: PreferenceViewModel) async {
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(preference.makeURL())
|
||||
session = try await StreamSessionBuilderFactory.shared.make(preference.makeURL())
|
||||
.setMode(.publish)
|
||||
.build()
|
||||
guard let session else {
|
||||
|
||||
@@ -11,15 +11,15 @@ nonisolated let logger = LBLogger.with("com.haishinkit.Screencast")
|
||||
|
||||
final class SampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
|
||||
private var slider: UISlider?
|
||||
private var session: Session?
|
||||
private var session: StreamSession?
|
||||
private var mixer = MediaMixer(captureSessionMode: .manual, multiTrackAudioMixingEnabled: true)
|
||||
private var needVideoConfiguration = true
|
||||
|
||||
override init() {
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
|
||||
await SRTLogger.shared.setLevel(.debug)
|
||||
await RTCLogger.shared.setLevel(.info)
|
||||
@@ -34,7 +34,7 @@ final class SampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
|
||||
// mixer.audioMixerSettings.tracks[1] = .default
|
||||
Task {
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(Preference.default.makeURL()).build()
|
||||
session = try await StreamSessionBuilderFactory.shared.make(Preference.default.makeURL()).build()
|
||||
// ReplayKit is sensitive to memory, so we limit the queue to a maximum of five items.
|
||||
var videoSetting = await mixer.videoMixerSettings
|
||||
videoSetting.mode = .passthrough
|
||||
|
||||
@@ -15,7 +15,7 @@ final class UVCViewModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
@Published var isShowError = false
|
||||
@Published private(set) var readyState: SessionReadyState = .closed
|
||||
@Published private(set) var readyState: StreamSessionReadyState = .closed
|
||||
@Published private(set) var isRecording = false
|
||||
@Published var isHDREnabled = false {
|
||||
didSet {
|
||||
@@ -36,7 +36,7 @@ final class UVCViewModel: ObservableObject {
|
||||
// let mixer = MediaMixer(captureSesionMode: .multi)
|
||||
private(set) var mixer = MediaMixer(captureSessionMode: .single)
|
||||
private var tasks: [Task<Void, Swift.Error>] = []
|
||||
private var session: (any Session)?
|
||||
private var session: (any StreamSession)?
|
||||
private var recorder: StreamRecorder?
|
||||
|
||||
init() {
|
||||
@@ -136,7 +136,7 @@ final class UVCViewModel: ObservableObject {
|
||||
func makeSession(_ preference: PreferenceViewModel) async {
|
||||
// Make session.
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(preference.makeURL())
|
||||
session = try await StreamSessionBuilderFactory.shared.make(preference.makeURL())
|
||||
.setMode(.publish)
|
||||
.build()
|
||||
guard let session else {
|
||||
|
||||
@@ -19,9 +19,9 @@ struct HaishinApp: App {
|
||||
|
||||
init() {
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
|
||||
await RTCLogger.shared.setLevel(.debug)
|
||||
await SRTLogger.shared.setLevel(.debug)
|
||||
|
||||
@@ -4,12 +4,12 @@ import SwiftUI
|
||||
|
||||
@MainActor
|
||||
final class PlaybackViewModel: ObservableObject {
|
||||
@Published private(set) var readyState: SessionReadyState = .closed
|
||||
@Published private(set) var readyState: StreamSessionReadyState = .closed
|
||||
@Published private(set) var error: Error?
|
||||
@Published var isShowError = false
|
||||
|
||||
private var view: PiPHKView?
|
||||
private var session: (any Session)?
|
||||
private var session: (any StreamSession)?
|
||||
private let audioPlayer = AudioPlayer(audioEngine: AVAudioEngine())
|
||||
private var pictureInPictureController: AVPictureInPictureController?
|
||||
|
||||
@@ -43,7 +43,7 @@ final class PlaybackViewModel: ObservableObject {
|
||||
|
||||
private func makeSession(_ preference: PreferenceViewModel) async {
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(preference.makeURL())
|
||||
session = try await StreamSessionBuilderFactory.shared.make(preference.makeURL())
|
||||
.setMode(.playback)
|
||||
.build()
|
||||
guard let session else {
|
||||
|
||||
@@ -10,10 +10,10 @@ final class PublishViewModel: ObservableObject {
|
||||
@Published private(set) var error: Error?
|
||||
@Published var isShowError = false
|
||||
@Published private(set) var isTorchEnabled = false
|
||||
@Published private(set) var readyState: SessionReadyState = .closed
|
||||
@Published private(set) var readyState: StreamSessionReadyState = .closed
|
||||
private(set) var mixer = MediaMixer(captureSessionMode: .multi)
|
||||
private var tasks: [Task<Void, Swift.Error>] = []
|
||||
private var session: (any Session)?
|
||||
private var session: (any StreamSession)?
|
||||
private var currentPosition: AVCaptureDevice.Position = .back
|
||||
@ScreenActor private var currentVideoEffect: VideoEffect?
|
||||
|
||||
@@ -49,7 +49,7 @@ final class PublishViewModel: ObservableObject {
|
||||
func makeSession(_ preference: PreferenceViewModel) async {
|
||||
// Make session.
|
||||
do {
|
||||
session = try await SessionBuilderFactory.shared.make(preference.makeURL())
|
||||
session = try await StreamSessionBuilderFactory.shared.make(preference.makeURL())
|
||||
.setMode(.publish)
|
||||
.build()
|
||||
guard let session else {
|
||||
|
||||
@@ -19,9 +19,9 @@ struct HaishinApp: App {
|
||||
|
||||
init() {
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(HTTPSessionFactory())
|
||||
|
||||
await RTCLogger.shared.setLevel(.debug)
|
||||
await SRTLogger.shared.setLevel(.debug)
|
||||
|
||||
@@ -16,8 +16,8 @@ struct HaishinApp: App {
|
||||
|
||||
init() {
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
# ``HaishinKit``
|
||||
メインモジュールです。
|
||||
|
||||
## 🔍 概要
|
||||
ライブストリーミングに必要なカメラやマイクのミキシング機能の提供を行います。各モジュールに対して共通の処理を提供します。
|
||||
|
||||
### モジュール構成
|
||||
|モジュール|説明|
|
||||
|:-|:-|
|
||||
|HaishinKit|本モジュールです。|
|
||||
|RTMPHaishinKit|RTMPプロトコルスタックを提供します。|
|
||||
|SRTHaishinKit|SRTプロトコルスタックを提供します。|
|
||||
|RTCHaishinKit|WebRTCのWHEP/WHIPプロトコルスタックを提供します。現在α版です。|
|
||||
|MoQTHaishinKit|MoQTプロトコルスタックを提供します。現在α版です。
|
||||
|
||||
## 🎨 機能
|
||||
以下の機能を提供しています。
|
||||
- ライブミキシング
|
||||
- [映像のミキシング](doc://HaishinKit/videomixing)
|
||||
- カメラ映像や静止画を一つの配信映像ソースとして扱います。
|
||||
- 音声のミキシング
|
||||
- 異なるマイク音声を合成して一つの配信音声ソースとして扱います。
|
||||
- Session
|
||||
- RTMP/SRT/WHEP/WHIPといったプロトコルを統一的なAPIで扱えます。
|
||||
|
||||
## 📖 利用方法
|
||||
### ライブミキシング
|
||||
```swift
|
||||
let mixer = MediaMixer()
|
||||
|
||||
Task {
|
||||
do {
|
||||
// Attaches the microphone device.
|
||||
try await mixer.attachAudio(AVCaptureDevice.default(for: .audio))
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
|
||||
do {
|
||||
// Attaches the camera device.
|
||||
try await mixer.attachVideo(AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back))
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
|
||||
// Associates the stream object with the MediaMixer.
|
||||
await mixer.addOutput(stream)
|
||||
await mixer.startRunning()
|
||||
}
|
||||
```
|
||||
|
||||
### Session api.
|
||||
RTMPやSRTとのクライアントとしての実装を統一的なAPIで扱えます。リトライ処理などもAPI内部で行います。
|
||||
|
||||
#### 前準備
|
||||
```swift
|
||||
import HaishinKit
|
||||
import RTMPHaishinKit
|
||||
import SRTHaishinKit
|
||||
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
}
|
||||
```
|
||||
|
||||
#### Sessionの作成
|
||||
```swift
|
||||
let session = try await SessionBuilderFactory.shared.make(URL(string: "rtmp://hostname/live/live"))
|
||||
.setMode(.ingest)
|
||||
.build()
|
||||
```
|
||||
```swift
|
||||
let session = try await SessionBuilderFactory.shared.make(URL(string: "srt://hostname:448?stream=xxxxx"))
|
||||
.setMode(.playback)
|
||||
.build()
|
||||
```
|
||||
|
||||
#### 接続
|
||||
配信や視聴を行います。
|
||||
```swift
|
||||
try session.connect {
|
||||
print("on disconnected")
|
||||
}
|
||||
```
|
||||
|
||||
@@ -50,7 +50,7 @@ Task {
|
||||
}
|
||||
```
|
||||
|
||||
### Session API
|
||||
### StreamSession API
|
||||
Provides a unified API for implementing clients with RTMP and SRT. Retry handling is also performed internally by the API.
|
||||
|
||||
#### Preparation
|
||||
@@ -60,22 +60,22 @@ import RTMPHaishinKit
|
||||
import SRTHaishinKit
|
||||
|
||||
Task {
|
||||
await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
}
|
||||
```
|
||||
|
||||
#### Make Session
|
||||
#### Make StreamSession
|
||||
**RTMP**
|
||||
Please provide the RTMP connection URL combined with the streamName.
|
||||
```swift
|
||||
let session = try await SessionBuilderFactory.shared.make(URL(string: "rtmp://hostname/appName/stramName"))
|
||||
let session = try await StreamSessionBuilderFactory.shared.make(URL(string: "rtmp://hostname/appName/stramName"))
|
||||
.setMode(.publish)
|
||||
.build()
|
||||
```
|
||||
**SRT**
|
||||
```swift
|
||||
let session = try await SessionBuilderFactory.shared.make(URL(string: "srt://hostname:448?stream=xxxxx"))
|
||||
let session = try await StreamSessionBuilderFactory.shared.make(URL(string: "srt://hostname:448?stream=xxxxx"))
|
||||
.setMode(.playback)
|
||||
.build()
|
||||
```
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public protocol SessionConfiguration: Encodable, Sendable {
|
||||
}
|
||||
+6
-6
@@ -1,9 +1,9 @@
|
||||
import Foundation
|
||||
|
||||
package let kSession_maxRetryCount: Int = 3
|
||||
package let kStreamSession_maxRetryCount: Int = 3
|
||||
|
||||
/// Represents the type of session to establish.
|
||||
public enum SessionMode: Sendable {
|
||||
public enum StreamSessionMode: Sendable {
|
||||
/// A publishing session, used to stream media from the local device to a server or peers.
|
||||
case publish
|
||||
/// A playback session, used to receive and play media streamed from a server or peers.
|
||||
@@ -11,7 +11,7 @@ public enum SessionMode: Sendable {
|
||||
}
|
||||
|
||||
/// Represents the current connection state of a session.
|
||||
public enum SessionReadyState: Int, Sendable {
|
||||
public enum StreamSessionReadyState: Int, Sendable {
|
||||
/// The session is currently attempting to establish a connection.
|
||||
case connecting
|
||||
/// The session has been successfully established and is ready for communication.
|
||||
@@ -27,15 +27,15 @@ public enum SessionReadyState: Int, Sendable {
|
||||
/// It is designed so that various streaming services can be used through a common API.
|
||||
/// While coding with the conventional Connection offered flexibility,
|
||||
/// it also required a certain level of maturity in properly handling network communication.
|
||||
public protocol Session: NetworkConnection {
|
||||
public protocol StreamSession: NetworkConnection {
|
||||
/// The current ready state.
|
||||
var readyState: AsyncStream<SessionReadyState> { get }
|
||||
var readyState: AsyncStream<StreamSessionReadyState> { get }
|
||||
|
||||
/// The stream instance.
|
||||
var stream: any StreamConvertible { get async }
|
||||
|
||||
/// Creates a new session with uri.
|
||||
init(uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?)
|
||||
init(uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?)
|
||||
|
||||
/// Sets a max retry count.
|
||||
func setMaxRetryCount(_ maxRetryCount: Int)
|
||||
+8
-8
@@ -1,31 +1,31 @@
|
||||
import Foundation
|
||||
|
||||
/// An actor that provides builder for Session object.
|
||||
public actor SessionBuilder {
|
||||
private let factory: SessionBuilderFactory
|
||||
public actor StreamSessionBuilder {
|
||||
private let factory: StreamSessionBuilderFactory
|
||||
private let uri: URL
|
||||
private var mode: SessionMode = .publish
|
||||
private var configuration: (any SessionConfiguration)?
|
||||
private var mode: StreamSessionMode = .publish
|
||||
private var configuration: (any StreamSessionConfiguration)?
|
||||
|
||||
init(factory: SessionBuilderFactory, uri: URL) {
|
||||
init(factory: StreamSessionBuilderFactory, uri: URL) {
|
||||
self.factory = factory
|
||||
self.uri = uri
|
||||
}
|
||||
|
||||
/// Sets a method.
|
||||
public func setMode(_ mode: SessionMode) -> Self {
|
||||
public func setMode(_ mode: StreamSessionMode) -> Self {
|
||||
self.mode = mode
|
||||
return self
|
||||
}
|
||||
|
||||
/// Sets a config.
|
||||
public func setConfiguration(_ configuration: (any SessionConfiguration)?) -> Self {
|
||||
public func setConfiguration(_ configuration: (any StreamSessionConfiguration)?) -> Self {
|
||||
self.configuration = configuration
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a Session instance with the specified fields.
|
||||
public func build() async throws -> (any Session)? {
|
||||
public func build() async throws -> (any StreamSession)? {
|
||||
return try await factory.build(uri, method: mode, configuration: configuration)
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -8,12 +8,12 @@ import Foundation
|
||||
/// import RTMPHaishinKit
|
||||
/// import SRTHaishinKit
|
||||
///
|
||||
/// await SessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
/// await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
/// await StreamSessionBuilderFactory.shared.register(RTMPSessionFactory())
|
||||
/// await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
/// ```
|
||||
public actor SessionBuilderFactory {
|
||||
public actor StreamSessionBuilderFactory {
|
||||
/// The shared instance.
|
||||
public static let shared = SessionBuilderFactory()
|
||||
public static let shared = StreamSessionBuilderFactory()
|
||||
|
||||
/// The error domain codes.
|
||||
public enum Error: Swift.Error {
|
||||
@@ -23,28 +23,28 @@ public actor SessionBuilderFactory {
|
||||
case notFound
|
||||
}
|
||||
|
||||
private var factories: [any SessionFactory] = []
|
||||
private var factories: [any StreamSessionFactory] = []
|
||||
|
||||
private init() {
|
||||
}
|
||||
|
||||
/// Makes a new session builder.
|
||||
public func make(_ uri: URL?) throws -> SessionBuilder {
|
||||
public func make(_ uri: URL?) throws -> StreamSessionBuilder {
|
||||
guard let uri else {
|
||||
throw Error.illegalArgument
|
||||
}
|
||||
return SessionBuilder(factory: self, uri: uri)
|
||||
return StreamSessionBuilder(factory: self, uri: uri)
|
||||
}
|
||||
|
||||
/// Registers a factory.
|
||||
public func register(_ factory: some SessionFactory) {
|
||||
public func register(_ factory: some StreamSessionFactory) {
|
||||
guard !factories.contains(where: { $0.supportedProtocols == factory.supportedProtocols }) else {
|
||||
return
|
||||
}
|
||||
factories.append(factory)
|
||||
}
|
||||
|
||||
func build(_ uri: URL?, method: SessionMode, configuration: (any SessionConfiguration)?) throws -> (any Session) {
|
||||
func build(_ uri: URL?, method: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) throws -> (any StreamSession) {
|
||||
guard let uri else {
|
||||
throw Error.illegalArgument
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import Foundation
|
||||
|
||||
public protocol StreamSessionConfiguration: Encodable, Sendable {
|
||||
}
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import Foundation
|
||||
|
||||
/// A type that represents a streaming session factory.
|
||||
public protocol SessionFactory {
|
||||
public protocol StreamSessionFactory {
|
||||
/// The supported protocols.
|
||||
var supportedProtocols: Set<String> { get }
|
||||
|
||||
/// Makes a new session by uri.
|
||||
func make(_ uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) -> any Session
|
||||
func make(_ uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) -> any StreamSession
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
actor HTTPSession: Session {
|
||||
actor HTTPSession: StreamSession {
|
||||
var connected: Bool {
|
||||
get async {
|
||||
peerConnection?.connectionState == .connected
|
||||
@@ -9,7 +9,7 @@ actor HTTPSession: Session {
|
||||
}
|
||||
|
||||
@AsyncStreamed(.closed)
|
||||
private(set) var readyState: AsyncStream<SessionReadyState>
|
||||
private(set) var readyState: AsyncStream<StreamSessionReadyState>
|
||||
|
||||
var stream: any StreamConvertible {
|
||||
_stream
|
||||
@@ -19,11 +19,11 @@ actor HTTPSession: Session {
|
||||
private var location: URL?
|
||||
private var maxRetryCount: Int = 0
|
||||
private var _stream = RTCStream()
|
||||
private var mode: SessionMode
|
||||
private var mode: StreamSessionMode
|
||||
private var configuration: HTTPSessionConfiguration?
|
||||
private var peerConnection: RTCPeerConnection?
|
||||
|
||||
init(uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) {
|
||||
init(uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) {
|
||||
logger.level = .debug
|
||||
self.uri = uri
|
||||
self.mode = mode
|
||||
|
||||
@@ -6,7 +6,7 @@ import HaishinKit
|
||||
/// an `RTCConfiguration` and applied when creating the underlying
|
||||
/// `RTCPeerConnection`.
|
||||
///
|
||||
public struct HTTPSessionConfiguration: SessionConfiguration, RTCConfigurationConvertible {
|
||||
public struct HTTPSessionConfiguration: StreamSessionConfiguration, RTCConfigurationConvertible {
|
||||
public var iceServers: [String] = []
|
||||
public var bindAddress: String?
|
||||
public var certificateType: RTCCertificateType?
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
public struct HTTPSessionFactory: SessionFactory {
|
||||
public struct HTTPSessionFactory: StreamSessionFactory {
|
||||
public let supportedProtocols: Set<String> = ["http", "https"]
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func make(_ uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) -> any Session {
|
||||
public func make(_ uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) -> any StreamSession {
|
||||
return HTTPSession(uri: uri, mode: mode, configuration: configuration)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
actor RTMPSession: Session {
|
||||
actor RTMPSession: StreamSession {
|
||||
var connected: Bool {
|
||||
get async {
|
||||
await connection.connected
|
||||
@@ -9,16 +9,16 @@ actor RTMPSession: Session {
|
||||
}
|
||||
|
||||
@AsyncStreamed(.closed)
|
||||
private(set) var readyState: AsyncStream<SessionReadyState>
|
||||
private(set) var readyState: AsyncStream<StreamSessionReadyState>
|
||||
|
||||
var stream: any StreamConvertible {
|
||||
_stream
|
||||
}
|
||||
|
||||
private let uri: RTMPURL
|
||||
private let mode: SessionMode
|
||||
private let mode: StreamSessionMode
|
||||
private var retryCount: Int = 0
|
||||
private var maxRetryCount = kSession_maxRetryCount
|
||||
private var maxRetryCount = kStreamSession_maxRetryCount
|
||||
private lazy var connection: RTMPConnection = {
|
||||
switch mode {
|
||||
case .publish:
|
||||
@@ -41,7 +41,7 @@ actor RTMPSession: Session {
|
||||
}
|
||||
}
|
||||
|
||||
init(uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) {
|
||||
init(uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) {
|
||||
self.uri = RTMPURL(url: uri)
|
||||
self.mode = mode
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
public struct RTMPSessionFactory: SessionFactory {
|
||||
public struct RTMPSessionFactory: StreamSessionFactory {
|
||||
public let supportedProtocols: Set<String> = ["rtmp", "rtmps"]
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func make(_ uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) -> any Session {
|
||||
public func make(_ uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) -> any StreamSession {
|
||||
return RTMPSession(uri: uri, mode: mode, configuration: configuration)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ try await connection.connect("srt://host:port?key=value")
|
||||
```swift
|
||||
import SRTHaishinKit
|
||||
|
||||
await SessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
await StreamSessionBuilderFactory.shared.register(SRTSessionFactory())
|
||||
```
|
||||
|
||||
## 🔧 Test
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
actor SRTSession: Session {
|
||||
actor SRTSession: StreamSession {
|
||||
var connected: Bool {
|
||||
get async {
|
||||
await connection.connected
|
||||
@@ -10,16 +10,16 @@ actor SRTSession: Session {
|
||||
}
|
||||
|
||||
@AsyncStreamed(.closed)
|
||||
private(set) var readyState: AsyncStream<SessionReadyState>
|
||||
private(set) var readyState: AsyncStream<StreamSessionReadyState>
|
||||
|
||||
var stream: any StreamConvertible {
|
||||
_stream
|
||||
}
|
||||
|
||||
private let uri: URL
|
||||
private let mode: SessionMode
|
||||
private let mode: StreamSessionMode
|
||||
private var retryCount: Int = 0
|
||||
private var maxRetryCount = kSession_maxRetryCount
|
||||
private var maxRetryCount = kStreamSession_maxRetryCount
|
||||
private lazy var connection = SRTConnection()
|
||||
private lazy var _stream: SRTStream = {
|
||||
SRTStream(connection: connection)
|
||||
@@ -31,7 +31,7 @@ actor SRTSession: Session {
|
||||
}
|
||||
}
|
||||
|
||||
init(uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) {
|
||||
init(uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) {
|
||||
self.uri = uri
|
||||
self.mode = mode
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Foundation
|
||||
import HaishinKit
|
||||
|
||||
public struct SRTSessionFactory: SessionFactory {
|
||||
public struct SRTSessionFactory: StreamSessionFactory {
|
||||
public let supportedProtocols: Set<String> = ["srt"]
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func make(_ uri: URL, mode: SessionMode, configuration: (any SessionConfiguration)?) -> any Session {
|
||||
public func make(_ uri: URL, mode: StreamSessionMode, configuration: (any StreamSessionConfiguration)?) -> any StreamSession {
|
||||
return SRTSession(uri: uri, mode: mode, configuration: configuration)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user