Created
July 17, 2022 18:34
-
-
Save yajamon/faf01e27c10fc8252dba9b3e5dbfb03e to your computer and use it in GitHub Desktop.
obs-websocket v5.0.0 に Swift からつなごうとしたあれこれ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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