mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
[WIP] Broadcasts
This commit is contained in:
parent
a7efc782e1
commit
552f9ff7ea
10 changed files with 117 additions and 17 deletions
|
|
@ -61,6 +61,8 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder {
|
|||
}
|
||||
return self.delayedFrames.remove(at: minFrameIndex)
|
||||
}
|
||||
} else {
|
||||
assert(true)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -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<NSNumber *> *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"];
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<Api.phone.JoinAsPeers>) {
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1930,7 +1930,7 @@ public struct GetAudioBroadcastPartResult {
|
|||
}
|
||||
|
||||
public func getAudioBroadcastPart(account: Account, callId: Int64, accessHash: Int64, datacenterId: Int, timestampId: Int32) -> Signal<GetAudioBroadcastPartResult, NoError> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ objc_library(
|
|||
"//third-party/boringssl:ssl",
|
||||
"//third-party/ogg:ogg",
|
||||
"//third-party/opusfile:opusfile",
|
||||
"//submodules/ffmpeg:ffmpeg",
|
||||
],
|
||||
sdk_frameworks = [
|
||||
"Foundation",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 2c55abafe21cf67128dc3733844e37276fbcabb3
|
||||
Subproject commit 43bd0ee8b629939e5bc05eae34b0f17e3263b3b3
|
||||
5
submodules/ffmpeg/BUILD
vendored
5
submodules/ffmpeg/BUILD
vendored
|
|
@ -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([
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue