From 552f9ff7eafd819459662398ee3f2d50dbf24451 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 8 Mar 2021 03:19:23 +0400 Subject: [PATCH] [WIP] Broadcasts --- .../Sources/FFMpegAudioFrameDecoder.swift | 2 + submodules/MtProtoKit/Sources/MTContext.m | 4 +- submodules/TelegramApi/Sources/Api0.swift | 5 +- submodules/TelegramApi/Sources/Api2.swift | 24 +++--- submodules/TelegramApi/Sources/Api4.swift | 74 +++++++++++++++++++ .../TelegramCore/Sources/GroupCalls.swift | 7 +- .../Sources/GroupCallContext.swift | 10 ++- submodules/TgVoipWebrtc/BUILD | 1 + submodules/TgVoipWebrtc/tgcalls | 2 +- submodules/ffmpeg/BUILD | 5 +- 10 files changed, 117 insertions(+), 17 deletions(-) diff --git a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift index c3d0d2b570..35909c025b 100644 --- a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift @@ -61,6 +61,8 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder { } return self.delayedFrames.remove(at: minFrameIndex) } + } else { + assert(true) } return nil diff --git a/submodules/MtProtoKit/Sources/MTContext.m b/submodules/MtProtoKit/Sources/MTContext.m index bde013a54e..b394ac923c 100644 --- a/submodules/MtProtoKit/Sources/MTContext.m +++ b/submodules/MtProtoKit/Sources/MTContext.m @@ -379,14 +379,14 @@ static int32_t fixedTimeDifferenceValue = 0; NSDictionary *datacenterAuthInfoById = [keychain objectForKey:@"datacenterAuthInfoById" group:@"persistent"]; if (datacenterAuthInfoById != nil) { _datacenterAuthInfoById = [[NSMutableDictionary alloc] initWithDictionary:datacenterAuthInfoById]; -#if DEBUG +/*#if DEBUG NSArray *keys = [_datacenterAuthInfoById allKeys]; for (NSNumber *key in keys) { if (parseAuthInfoMapKeyInteger(key).selector != MTDatacenterAuthInfoSelectorPersistent) { [_datacenterAuthInfoById removeObjectForKey:key]; } } -#endif +#endif*/ } NSDictionary *datacenterPublicKeysById = [keychain objectForKey:@"datacenterPublicKeysById" group:@"ephemeral"]; diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 5746e7cb7f..91c31498ad 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -500,6 +500,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1038136962] = { return Api.EncryptedFile.parse_encryptedFileEmpty($0) } dict[1248893260] = { return Api.EncryptedFile.parse_encryptedFile($0) } dict[-557924733] = { return Api.CodeSettings.parse_codeSettings($0) } + dict[-1343921601] = { return Api.phone.JoinAsPeers.parse_joinAsPeers($0) } dict[-391902247] = { return Api.SecureValueError.parse_secureValueErrorData($0) } dict[12467706] = { return Api.SecureValueError.parse_secureValueErrorFrontSide($0) } dict[-2037765467] = { return Api.SecureValueError.parse_secureValueErrorReverseSide($0) } @@ -667,7 +668,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-667654413] = { return Api.InputFileLocation.parse_inputPhotoLegacyFileLocation($0) } dict[668375447] = { return Api.InputFileLocation.parse_inputPeerPhotoFileLocation($0) } dict[230353641] = { return Api.InputFileLocation.parse_inputStickerSetThumb($0) } - dict[-775148961] = { return Api.InputFileLocation.parse_inputGroupCallStream($0) } + dict[-1146808775] = { return Api.InputFileLocation.parse_inputGroupCallStream($0) } dict[286776671] = { return Api.GeoPoint.parse_geoPointEmpty($0) } dict[-1297942941] = { return Api.GeoPoint.parse_geoPoint($0) } dict[506920429] = { return Api.InputPhoneCall.parse_inputPhoneCall($0) } @@ -1246,6 +1247,8 @@ public struct Api { _1.serialize(buffer, boxed) case let _1 as Api.CodeSettings: _1.serialize(buffer, boxed) + case let _1 as Api.phone.JoinAsPeers: + _1.serialize(buffer, boxed) case let _1 as Api.SecureValueError: _1.serialize(buffer, boxed) case let _1 as Api.InputStickerSetItem: diff --git a/submodules/TelegramApi/Sources/Api2.swift b/submodules/TelegramApi/Sources/Api2.swift index 8ec11d5de7..bcb055e5d5 100644 --- a/submodules/TelegramApi/Sources/Api2.swift +++ b/submodules/TelegramApi/Sources/Api2.swift @@ -17025,7 +17025,7 @@ public extension Api { case inputPhotoLegacyFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, volumeId: Int64, localId: Int32, secret: Int64) case inputPeerPhotoFileLocation(flags: Int32, peer: Api.InputPeer, volumeId: Int64, localId: Int32) case inputStickerSetThumb(stickerset: Api.InputStickerSet, volumeId: Int64, localId: Int32) - case inputGroupCallStream(call: Api.InputGroupCall, date: Int32) + case inputGroupCallStream(call: Api.InputGroupCall, timeMs: Int64, scale: Int32) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -17104,12 +17104,13 @@ public extension Api { serializeInt64(volumeId, buffer: buffer, boxed: false) serializeInt32(localId, buffer: buffer, boxed: false) break - case .inputGroupCallStream(let call, let date): + case .inputGroupCallStream(let call, let timeMs, let scale): if boxed { - buffer.appendInt32(-775148961) + buffer.appendInt32(-1146808775) } call.serialize(buffer, true) - serializeInt32(date, buffer: buffer, boxed: false) + serializeInt64(timeMs, buffer: buffer, boxed: false) + serializeInt32(scale, buffer: buffer, boxed: false) break } } @@ -17134,8 +17135,8 @@ public extension Api { return ("inputPeerPhotoFileLocation", [("flags", flags), ("peer", peer), ("volumeId", volumeId), ("localId", localId)]) case .inputStickerSetThumb(let stickerset, let volumeId, let localId): return ("inputStickerSetThumb", [("stickerset", stickerset), ("volumeId", volumeId), ("localId", localId)]) - case .inputGroupCallStream(let call, let date): - return ("inputGroupCallStream", [("call", call), ("date", date)]) + case .inputGroupCallStream(let call, let timeMs, let scale): + return ("inputGroupCallStream", [("call", call), ("timeMs", timeMs), ("scale", scale)]) } } @@ -17302,12 +17303,15 @@ public extension Api { if let signature = reader.readInt32() { _1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall } - var _2: Int32? - _2 = reader.readInt32() + var _2: Int64? + _2 = reader.readInt64() + var _3: Int32? + _3 = reader.readInt32() let _c1 = _1 != nil let _c2 = _2 != nil - if _c1 && _c2 { - return Api.InputFileLocation.inputGroupCallStream(call: _1!, date: _2!) + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.InputFileLocation.inputGroupCallStream(call: _1!, timeMs: _2!, scale: _3!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api4.swift b/submodules/TelegramApi/Sources/Api4.swift index 48bd6335f2..c1ffe0b052 100644 --- a/submodules/TelegramApi/Sources/Api4.swift +++ b/submodules/TelegramApi/Sources/Api4.swift @@ -1610,6 +1610,66 @@ public struct photos { } public extension Api { public struct phone { + public enum JoinAsPeers: TypeConstructorDescription { + case joinAsPeers(peers: [Api.Peer], chats: [Api.Chat], users: [Api.User]) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .joinAsPeers(let peers, let chats, let users): + if boxed { + buffer.appendInt32(-1343921601) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(peers.count)) + for item in peers { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(chats.count)) + for item in chats { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users.count)) + for item in users { + item.serialize(buffer, true) + } + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .joinAsPeers(let peers, let chats, let users): + return ("joinAsPeers", [("peers", peers), ("chats", chats), ("users", users)]) + } + } + + public static func parse_joinAsPeers(_ reader: BufferReader) -> JoinAsPeers? { + var _1: [Api.Peer]? + if let _ = reader.readInt32() { + _1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Peer.self) + } + var _2: [Api.Chat]? + if let _ = reader.readInt32() { + _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) + } + var _3: [Api.User]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.phone.JoinAsPeers.joinAsPeers(peers: _1!, chats: _2!, users: _3!) + } + else { + return nil + } + } + + } public enum GroupCall: TypeConstructorDescription { case groupCall(call: Api.GroupCall, participants: [Api.GroupCallParticipant], participantsNextOffset: String, chats: [Api.Chat], users: [Api.User]) @@ -7794,6 +7854,20 @@ public extension Api { return result }) } + + public static func getGroupCallJoinAs(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-277077702) + peer.serialize(buffer, true) + return (FunctionDescription(name: "phone.getGroupCallJoinAs", parameters: [("peer", peer)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.phone.JoinAsPeers? in + let reader = BufferReader(buffer) + var result: Api.phone.JoinAsPeers? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.phone.JoinAsPeers + } + return result + }) + } } } } diff --git a/submodules/TelegramCore/Sources/GroupCalls.swift b/submodules/TelegramCore/Sources/GroupCalls.swift index 75f4e4e4e8..9ac9560894 100644 --- a/submodules/TelegramCore/Sources/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/GroupCalls.swift @@ -1930,7 +1930,7 @@ public struct GetAudioBroadcastPartResult { } public func getAudioBroadcastPart(account: Account, callId: Int64, accessHash: Int64, datacenterId: Int, timestampId: Int32) -> Signal { - return account.network.multiplexedRequestManager.requestWithAdditionalInfo(to: .main(datacenterId), consumerId: Int64.random(in: 0 ..< Int64.max), data: Api.functions.upload.getFile(flags: 0, location: .inputGroupCallStream(call: .inputGroupCall(id: callId, accessHash: accessHash), date: timestampId), offset: 0, limit: 128 * 1024), tag: nil, continueInBackground: false, automaticFloodWait: false) + return account.network.multiplexedRequestManager.requestWithAdditionalInfo(to: .main(datacenterId), consumerId: Int64.random(in: 0 ..< Int64.max), data: Api.functions.upload.getFile(flags: 0, location: .inputGroupCallStream(call: .inputGroupCall(id: callId, accessHash: accessHash), timeMs: Int64(timestampId) * 1000, scale: 0), offset: 0, limit: 128 * 1024), tag: nil, continueInBackground: false, automaticFloodWait: false) |> map { result, responseTimestamp -> GetAudioBroadcastPartResult in switch result { case let .file(_, _, bytes): @@ -1956,6 +1956,11 @@ public func getAudioBroadcastPart(account: Account, callId: Int64, accessHash: I status: .notReady, responseTimestamp: responseTimestamp )) + } else if error.errorDescription == "DATE_INVALID" { + return .single(GetAudioBroadcastPartResult( + status: .tooOld, + responseTimestamp: responseTimestamp + )) } else { return .single(GetAudioBroadcastPartResult( status: .notReady, diff --git a/submodules/TelegramVoip/Sources/GroupCallContext.swift b/submodules/TelegramVoip/Sources/GroupCallContext.swift index 11a090d1b6..4a395be562 100644 --- a/submodules/TelegramVoip/Sources/GroupCallContext.swift +++ b/submodules/TelegramVoip/Sources/GroupCallContext.swift @@ -42,7 +42,7 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource { private let accessHash: Int64 private var datacenterId: Int? - + private let dumpDir: TempBoxDirectory init(queue: Queue, account: Account, callId: Int64, accessHash: Int64, datacenterId: Int?) { self.queue = queue @@ -50,6 +50,9 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource { self.callId = callId self.accessHash = accessHash self.datacenterId = datacenterId + + self.dumpDir = TempBox.shared.tempDirectory() + print("dumpDir = \(self.dumpDir.path)") } func requestPart(timestamp: Int32, completion: @escaping (OngoingGroupCallBroadcastPart) -> Void, rejoinNeeded: @escaping () -> Void) -> Disposable { @@ -80,6 +83,8 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource { } } |> deliverOn(self.queue) + + let dumpDir = self.dumpDir return signal.start(next: { result in guard let result = result else { @@ -89,6 +94,9 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource { let part: OngoingGroupCallBroadcastPart switch result.status { case let .data(dataValue): + let filePath = dumpDir.path + "/\(timestampId).ogg" + let _ = try? dataValue.write(to: URL(fileURLWithPath: filePath)) + part = OngoingGroupCallBroadcastPart(timestamp: timestampId, responseTimestamp: result.responseTimestamp, status: .success, oggData: dataValue) case .notReady: part = OngoingGroupCallBroadcastPart(timestamp: timestampId, responseTimestamp: result.responseTimestamp, status: .notReady, oggData: Data()) diff --git a/submodules/TgVoipWebrtc/BUILD b/submodules/TgVoipWebrtc/BUILD index bd281b1b2c..2a720c8217 100644 --- a/submodules/TgVoipWebrtc/BUILD +++ b/submodules/TgVoipWebrtc/BUILD @@ -54,6 +54,7 @@ objc_library( "//third-party/boringssl:ssl", "//third-party/ogg:ogg", "//third-party/opusfile:opusfile", + "//submodules/ffmpeg:ffmpeg", ], sdk_frameworks = [ "Foundation", diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 2c55abafe2..43bd0ee8b6 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 2c55abafe21cf67128dc3733844e37276fbcabb3 +Subproject commit 43bd0ee8b629939e5bc05eae34b0f17e3263b3b3 diff --git a/submodules/ffmpeg/BUILD b/submodules/ffmpeg/BUILD index 8ba94fb0b2..34a373f3c7 100644 --- a/submodules/ffmpeg/BUILD +++ b/submodules/ffmpeg/BUILD @@ -175,19 +175,22 @@ genrule( mkdir -p "$$YASM_DIR" tar -xf "$(location //third-party/yasm:yasm.tar)" -C "$$YASM_DIR" + VARIANT=release + if [ "$(TARGET_CPU)" == "ios_armv7" ]; then BUILD_ARCH="armv7" elif [ "$(TARGET_CPU)" == "ios_arm64" ]; then BUILD_ARCH="arm64" elif [ "$(TARGET_CPU)" == "ios_sim_arm64" ]; then BUILD_ARCH="sim_arm64" + VARIANT="debug" elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then BUILD_ARCH="x86_64" else echo "Unsupported architecture $(TARGET_CPU)" fi - PATH="$$PATH:$$YASM_DIR" "$$SOURCE_PATH/build-ffmpeg-bazel.sh" release "$$BUILD_ARCH" "$$BUILD_DIR" "$$SOURCE_PATH" + PATH="$$PATH:$$YASM_DIR" "$$SOURCE_PATH/build-ffmpeg-bazel.sh" "$$VARIANT" "$$BUILD_ARCH" "$$BUILD_DIR" "$$SOURCE_PATH" """ + "\n" + "\n".join([ "cp \"$$BUILD_DIR/FFmpeg-iOS/include/{header_path}\" \"$(location Public/ffmpeg/{header_path})\"".format(header_path = header_path) for header_path in ffmpeg_header_paths ]) + "\n" + "\n".join([