Skip to content

Instantly share code, notes, and snippets.

@yajamon
Created July 17, 2022 18:34
Show Gist options
  • Save yajamon/faf01e27c10fc8252dba9b3e5dbfb03e to your computer and use it in GitHub Desktop.
Save yajamon/faf01e27c10fc8252dba9b3e5dbfb03e to your computer and use it in GitHub Desktop.
obs-websocket v5.0.0 に Swift からつなごうとしたあれこれ
import UIKit
import Foundation
let decoder = JSONDecoder()
let encoder = JSONEncoder()
struct ObsMessage {
struct OpCodeOnly {
let op: Int
}
struct Unknown: Codable {
let op: Int
let d: D?
typealias D = Dictionary<String, String>
}
struct Hello: Codable {
/// op: 0
let op: Int
let d: D
struct D: Codable {
let obsWebSocketVersion: String
let rpcVersion: Int
}
}
struct Identify: Codable {
/// op: 1
let op: Int
let d: D
struct D: Codable {
let rpcVersion: Int
}
}
struct Identified: Codable {
/// op: 2
let op: Int
let d: D
struct D: Codable {
let negotiatedRpcVersion: Int
}
}
struct Reidentify: Codable {
/// op: 3
let op: Int
let d: D
struct D: Codable {
let eventSubscriptions: EventSubscription?
}
struct EventSubscription: OptionSet, Codable {
var rawValue: Int
}
}
}
extension ObsMessage {
static func identify() -> Identify {
.init(op: 1, d: .init(rpcVersion: 1))
}
static func reidentify() -> Reidentify {
.init(op: 3, d: .init(eventSubscriptions: nil))
}
}
extension ObsMessage.Hello {
static func from(webSocketTaskMessage message: URLSessionWebSocketTask.Message) throws -> Self {
guard case .string(let msg) = message else {
print("Hello message is not String")
let e = NSError()
throw e
}
return try decoder.decode(Self.self, from: msg.data(using: .utf8)!)
}
}
extension ObsMessage.Identified {
static func from(webSocketTaskMessage message: URLSessionWebSocketTask.Message) throws -> Self {
guard case .string(let msg) = message else {
print("Hello message is not String")
let e = NSError()
throw e
}
return try decoder.decode(Self.self, from: msg.data(using: .utf8)!)
}
}
class Handler: NSObject {
}
extension Handler: URLSessionDelegate{
}
extension Handler: URLSessionTaskDelegate{
}
extension Handler: URLSessionWebSocketDelegate {
func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
print("WebSocket did open. protocol:", `protocol` ?? "none")
Task {
let hello_msg = try await webSocketTask.receive()
print("hello_msg:", hello_msg)
let hello = try! ObsMessage.Hello.from(webSocketTaskMessage: hello_msg)
print("decoded: ", hello)
let identify = try! encoder.encode(ObsMessage.identify())
try await webSocketTask.send(.string(String(data: identify, encoding: .utf8)!))
let identified_msg = try await webSocketTask.receive()
let identified = try! ObsMessage.Identified.from(webSocketTaskMessage: identified_msg)
print("identified: ", identified)
let reidentidy = try! encoder.encode(ObsMessage.reidentify())
try await webSocketTask.send(.string(String(data: reidentidy, encoding: .utf8)!))
let reidentified_msg = try await webSocketTask.receive()
let reidentified = try! ObsMessage.Identified.from(webSocketTaskMessage: reidentified_msg)
print("reidentified: ", reidentified)
// event loop
while(true) {
let msg = try await webSocketTask.receive()
print("msg:", msg)
}
}
}
func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
print("WebSocket did close. closeCode:", closeCode)
}
}
let host = "192.168.1.x"
let port = "4455" // default of obs-websocket v5.0.0
let endpoint = URL(string: "ws://\(host):\(port)")!
var req = URLRequest(url: endpoint)
req.setValue("obswebsocket.json", forHTTPHeaderField: "Sec-WebSocket-Protocol")
let s = URLSession.shared
// let t = s.webSocketTask(with: endpoint)
let t = s.webSocketTask(with: endpoint, protocols: ["obswebsocket.json"])
// let t = s.webSocketTask(with: req)
let delegate = Handler()
t.delegate = delegate
t.resume()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment