diff --git a/YTLiveStreaming/API/YTLiveStreaming.swift b/YTLiveStreaming/API/YTLiveStreaming.swift index d339f96..c95b5c4 100644 --- a/YTLiveStreaming/API/YTLiveStreaming.swift +++ b/YTLiveStreaming/API/YTLiveStreaming.swift @@ -150,6 +150,9 @@ extension YTLiveStreaming { body.title, description: liveStreamDescription, streamName: liveStreamName, + frameRate: body.frameRate, + ingestionType: body.ingestionType, + resolution: body.resolution, isReusable: body.isReusable ) { result in switch result { diff --git a/YTLiveStreaming/LiveBroadcasts/LiveBroadcastStreamModel.swift b/YTLiveStreaming/LiveBroadcasts/LiveBroadcastStreamModel.swift index 41c88a3..a0374be 100644 --- a/YTLiveStreaming/LiveBroadcasts/LiveBroadcastStreamModel.swift +++ b/YTLiveStreaming/LiveBroadcasts/LiveBroadcastStreamModel.swift @@ -132,7 +132,7 @@ public struct LiveBroadcastStreamModel: Codable { public struct ContentDetails: Codable { public let boundStreamId: String? - public let boundStreamLastUpdateTimeMs: Int + private var _boundStreamLastUpdateTimeMs: String? // The date and time that the live stream referenced by boundStreamId was last updated. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format. public let monitorStream: MonitorStream public let enableEmbed: Bool public let enableDvr: Bool @@ -141,9 +141,31 @@ public struct LiveBroadcastStreamModel: Codable { public let closedCaptionsType: String public let projection: String public let enableLowLatency: Bool - public let latencyPreference: Bool + public let latencyPreference: String public let enableAutoStart: Bool public let enableAutoStop: Bool + + public var boundStreamLastUpdateTimeMs: Date? { + get { + getDate(for: _boundStreamLastUpdateTimeMs) + } + set { + _boundStreamLastUpdateTimeMs = setDate(for: newValue) + } + } + + private func getDate(for value: String?) -> Date? { + guard let value else { return nil } + return convertJSONtoDate(date: value) + } + + private func setDate(for value: Date?) -> String? { + if let value { + return value.toJSONformat() + } else { + return nil + } + } } public struct MonitorStream: Codable { @@ -156,7 +178,7 @@ public struct LiveBroadcastStreamModel: Codable { public let lifeCycleStatus: String public var privacyStatus: String public let recordingStatus: String - public let madeForKids: Bool + public let madeForKids: Bool? public let selfDeclaredMadeForKids: Bool } } @@ -195,9 +217,13 @@ public struct PostLiveBroadcastBody { let enableMonitorStream: Bool // contentDetails.monitorStream.enableMonitorStream let broadcastStreamDelayMs: Int // contentDetails.monitorStream.broadcastStreamDelayMs let privacyStatus: String // status.privacyStatus ("public" + let frameRate: String? // For LiveStream insert used. cdn.frameRate + let ingestionType: String? // For LiveStream insert used. cdn.ingestionType + let resolution: String? // For LiveStream insert used. cdn.resolution let isReusable: Bool // For LiveStream insert used. Indicates whether the stream is reusable, which means that it can be bound to multiple broadcasts. It is common for broadcasters to reuse the same stream for many different broadcasts if those broadcasts occur at different times. - public init(title: String, scheduledStartTime: Date, description: String, scheduledEndTime: Date, selfDeclaredMadeForKids: Bool, enableAutoStart: Bool, enableAutoStop: Bool, enableClosedCaptions: Bool, enableDvr: Bool, enableEmbed: Bool, recordFromStart: Bool, enableMonitorStream: Bool, broadcastStreamDelayMs: Int, privacyStatus: String, isReusable: Bool) { + public init(title: String, scheduledStartTime: Date, description: String, scheduledEndTime: Date, selfDeclaredMadeForKids: Bool, enableAutoStart: Bool, enableAutoStop: Bool, enableClosedCaptions: Bool, enableDvr: Bool, enableEmbed: Bool, recordFromStart: Bool, enableMonitorStream: Bool, broadcastStreamDelayMs: Int, privacyStatus: String, + frameRate: String? = nil, ingestionType: String? = nil, resolution: String? = nil, isReusable: Bool) { self.title = title self.scheduledStartTime = scheduledStartTime self.description = description @@ -212,6 +238,9 @@ public struct PostLiveBroadcastBody { self.enableMonitorStream = enableMonitorStream self.broadcastStreamDelayMs = broadcastStreamDelayMs self.privacyStatus = privacyStatus + self.frameRate = frameRate + self.ingestionType = ingestionType + self.resolution = resolution self.isReusable = isReusable } } diff --git a/YTLiveStreaming/LiveStreamingRequests/YTLiveRequest.swift b/YTLiveStreaming/LiveStreamingRequests/YTLiveRequest.swift index 270f760..850b719 100644 --- a/YTLiveStreaming/LiveStreamingRequests/YTLiveRequest.swift +++ b/YTLiveStreaming/LiveStreamingRequests/YTLiveRequest.swift @@ -476,6 +476,9 @@ extension YTLiveRequest { class func createLiveStream(_ title: String, description: String, streamName: String, + frameRate: String? = nil, + ingestionType: String? = nil, + resolution: String? = nil, isReusable: Bool, completion: @escaping (Result) -> Void) { getHeaders { headers in @@ -483,14 +486,16 @@ extension YTLiveRequest { completion(.failure(.message("OAuth token is not presented"))) return } - let jsonBody = CreateLiveStreamBody(title: title, description: description, streamName: streamName, isReusable: isReusable) + let jsonBody = CreateLiveStreamBody(title: title, description: description, streamName: streamName, + frameRate: frameRate, ingestionType: ingestionType, resolution: resolution, + isReusable: isReusable) guard let jsonData = try? JSONEncoder().encode(jsonBody), let jsonString = String(data: jsonData, encoding: .utf8) else { completion(.failure(.message("Failed while preparing request"))) return } let encoder = JSONBodyStringEncoding(jsonBody: jsonString) - let url = "\(LiveAPI.BaseURL)/liveStreams?part=id,snippet,cdn,status&key=\(Credentials.APIkey)" + let url = "\(LiveAPI.BaseURL)/liveStreams?part=id,snippet,cdn,contentDetails,status&key=\(Credentials.APIkey)" AF.request(url, method: .post, parameters: [:], encoding: encoder, headers: headers) .validate() .responseData { response in diff --git a/YTLiveStreaming/LiveStreams/UpdateLiveStreamsBody.swift b/YTLiveStreaming/LiveStreams/UpdateLiveStreamsBody.swift index 2b472e1..67ee38b 100644 --- a/YTLiveStreaming/LiveStreams/UpdateLiveStreamsBody.swift +++ b/YTLiveStreaming/LiveStreams/UpdateLiveStreamsBody.swift @@ -36,14 +36,16 @@ struct CreateLiveStreamBody: Codable { } struct Cdn: Codable { + let streamName: String var frameRate: String var ingestionType: String var resolution: String - init(streamName: String) { - frameRate = LiveAPI.FrameRate - ingestionType = LiveAPI.IngestionType - resolution = LiveAPI.Resolution + init(streamName: String, frameRate: String? = nil, ingestionType: String? = nil, resolution: String? = nil) { + self.streamName = streamName + self.frameRate = frameRate ?? LiveAPI.FrameRate + self.ingestionType = ingestionType ?? LiveAPI.IngestionType + self.resolution = resolution ?? LiveAPI.Resolution } } @@ -51,9 +53,10 @@ struct CreateLiveStreamBody: Codable { let cdn: Cdn let contentDetails: ContentDetails - init(title: String, description: String, streamName: String, isReusable: Bool) { + init(title: String, description: String, streamName: String, frameRate: String? = nil, + ingestionType: String? = nil, resolution: String? = nil, isReusable: Bool) { snippet = Snipped(title: title, description: description) - cdn = Cdn(streamName: streamName) + cdn = Cdn(streamName: streamName, frameRate: frameRate, ingestionType: ingestionType, resolution: resolution) contentDetails = ContentDetails(isReusable: isReusable) } }