mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Broadcasts updates
This commit is contained in:
parent
dc038797b6
commit
bc472b2126
@ -587,9 +587,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
if let strongSelf = self {
|
||||
if value {
|
||||
if let audioSessionControl = strongSelf.audioSessionControl {
|
||||
let audioSessionActive: Signal<Bool, NoError>
|
||||
//let audioSessionActive: Signal<Bool, NoError>
|
||||
if let callKitIntegration = strongSelf.callKitIntegration {
|
||||
audioSessionActive = callKitIntegration.audioSessionActive
|
||||
_ = callKitIntegration.audioSessionActive
|
||||
|> filter { $0 }
|
||||
|> timeout(2.0, queue: Queue.mainQueue(), alternate: Signal { subscriber in
|
||||
if let strongSelf = self, let _ = strongSelf.audioSessionControl {
|
||||
@ -777,11 +777,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
}
|
||||
let temporaryParticipantsContext = GroupCallParticipantsContext(account: self.account, peerId: self.peerId, myPeerId: myPeerId, id: sourceContext.id, accessHash: sourceContext.accessHash, state: initialState)
|
||||
self.temporaryParticipantsContext = temporaryParticipantsContext
|
||||
self.participantsContextStateDisposable.set(combineLatest(queue: .mainQueue(),
|
||||
self.participantsContextStateDisposable.set((combineLatest(queue: .mainQueue(),
|
||||
myPeer,
|
||||
temporaryParticipantsContext.state,
|
||||
temporaryParticipantsContext.activeSpeakers
|
||||
).start(next: { [weak self] myPeerAndCachedData, state, activeSpeakers in
|
||||
)
|
||||
|> take(1)).start(next: { [weak self] myPeerAndCachedData, state, activeSpeakers in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -853,7 +854,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
|
||||
strongSelf.membersValue = members
|
||||
|
||||
strongSelf.stateValue.adminIds = state.adminIds
|
||||
var stateValue = strongSelf.stateValue
|
||||
stateValue.myPeerId = strongSelf.joinAsPeerId
|
||||
stateValue.adminIds = state.adminIds
|
||||
|
||||
strongSelf.stateValue = stateValue
|
||||
|
||||
strongSelf.summaryParticipantsState.set(.single(SummaryParticipantsState(
|
||||
participantCount: state.totalCount,
|
||||
@ -911,13 +916,13 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
}
|
||||
strongSelf.maybeRequestParticipants(ssrcs: ssrcs)
|
||||
}
|
||||
}, audioStreamData: OngoingGroupCallContext.AudioStreamData(account: self.accountContext.account, callId: callInfo.id, accessHash: callInfo.accessHash, datacenterId: callInfo.streamDcId.flatMap(Int.init)), rejoinNeeded: { [weak self] in
|
||||
}, audioStreamData: OngoingGroupCallContext.AudioStreamData(account: self.accountContext.account, callId: callInfo.id, accessHash: callInfo.accessHash), rejoinNeeded: { [weak self] in
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case .established = strongSelf.internalState {
|
||||
//strongSelf.requestCall()
|
||||
strongSelf.requestCall()
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1478,10 +1483,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
|
||||
let previousPeerId = strongSelf.joinAsPeerId
|
||||
strongSelf.joinAsPeerId = peerId
|
||||
strongSelf.stateValue.myPeerId = peerId
|
||||
|
||||
if let participantsContext = strongSelf.participantsContext, let immediateState = participantsContext.immediateState {
|
||||
strongSelf.switchToTemporaryParticipantsContext(sourceContext: participantsContext, initialState: immediateState, oldMyPeerId: previousPeerId)
|
||||
} else {
|
||||
strongSelf.stateValue.myPeerId = peerId
|
||||
}
|
||||
|
||||
strongSelf.requestCall()
|
||||
|
@ -325,7 +325,57 @@ class Download: NSObject, MTRequestMessageServiceDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func rawRequest(_ data: (FunctionDescription, Buffer, (Buffer) -> Any?), automaticFloodWait: Bool = true) -> Signal<(Any, Double), (MTRpcError, Double)> {
|
||||
func requestWithAdditionalData<T>(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse<T>), automaticFloodWait: Bool = true, failOnServerErrors: Bool = false) -> Signal<(T, Double), (MTRpcError, Double)> {
|
||||
return Signal { subscriber in
|
||||
let request = MTRequest()
|
||||
|
||||
request.setPayload(data.1.makeData() as Data, metadata: WrappedRequestMetadata(metadata: WrappedFunctionDescription(data.0), tag: nil), shortMetadata: WrappedRequestShortMetadata(shortMetadata: WrappedShortFunctionDescription(data.0)), responseParser: { response in
|
||||
if let result = data.2.parse(Buffer(data: response)) {
|
||||
return BoxedMessage(result)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
request.dependsOnPasswordEntry = false
|
||||
|
||||
request.shouldContinueExecutionWithErrorContext = { errorContext in
|
||||
guard let errorContext = errorContext else {
|
||||
return true
|
||||
}
|
||||
if errorContext.floodWaitSeconds > 0 && !automaticFloodWait {
|
||||
return false
|
||||
}
|
||||
if errorContext.internalServerErrorCount > 0 && failOnServerErrors {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
request.completed = { (boxedResponse, timestamp, error) -> () in
|
||||
if let error = error {
|
||||
subscriber.putError((error, timestamp))
|
||||
} else {
|
||||
if let result = (boxedResponse as! BoxedMessage).body as? T {
|
||||
subscriber.putNext((result, timestamp))
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
else {
|
||||
subscriber.putError((MTRpcError(errorCode: 500, errorDescription: "TL_VERIFICATION_ERROR"), timestamp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let internalId: Any! = request.internalId
|
||||
|
||||
self.requestService.add(request)
|
||||
|
||||
return ActionDisposable {
|
||||
self.requestService.removeRequest(byInternalId: internalId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rawRequest(_ data: (FunctionDescription, Buffer, (Buffer) -> Any?), automaticFloodWait: Bool = true, failOnServerErrors: Bool = false) -> Signal<(Any, Double), (MTRpcError, Double)> {
|
||||
let requestService = self.requestService
|
||||
return Signal { subscriber in
|
||||
let request = MTRequest()
|
||||
@ -346,6 +396,9 @@ class Download: NSObject, MTRequestMessageServiceDelegate {
|
||||
if errorContext.floodWaitSeconds > 0 && !automaticFloodWait {
|
||||
return false
|
||||
}
|
||||
if errorContext.internalServerErrorCount > 0 && failOnServerErrors {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -516,7 +516,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
|
||||
state.adminIds = adminIds
|
||||
|
||||
switch result {
|
||||
case let .groupCall(call, participants, _, chats, users):
|
||||
case let .groupCall(call, _, _, chats, users):
|
||||
guard let _ = GroupCallInfo(call) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
@ -821,7 +821,7 @@ public final class GroupCallParticipantsContext {
|
||||
|
||||
for i in 0 ..< self.participants.count {
|
||||
if let index = indexMap[self.participants[i].peer.id] {
|
||||
self.participants[i].mergeActivity(from: other.participants[i])
|
||||
self.participants[i].mergeActivity(from: other.participants[index])
|
||||
}
|
||||
}
|
||||
|
||||
@ -1900,19 +1900,34 @@ private func mergeAndSortParticipants(current currentParticipants: [GroupCallPar
|
||||
return mergedParticipants
|
||||
}
|
||||
|
||||
public func getAudioBroadcastDatacenter(account: Account, callId: Int64, accessHash: Int64) -> Signal<Int?, NoError> {
|
||||
public final class AudioBroadcastDataSource {
|
||||
fileprivate let download: Download
|
||||
|
||||
fileprivate init(download: Download) {
|
||||
self.download = download
|
||||
}
|
||||
}
|
||||
|
||||
public func getAudioBroadcastDataSource(account: Account, callId: Int64, accessHash: Int64) -> Signal<AudioBroadcastDataSource?, NoError> {
|
||||
return account.network.request(Api.functions.phone.getGroupCall(call: .inputGroupCall(id: callId, accessHash: accessHash)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.phone.GroupCall?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { result -> Int? in
|
||||
|> mapToSignal { result -> Signal<AudioBroadcastDataSource?, NoError> in
|
||||
guard let result = result else {
|
||||
return nil
|
||||
return .single(nil)
|
||||
}
|
||||
switch result {
|
||||
case let .groupCall(call, _, _, _, _):
|
||||
return GroupCallInfo(call)?.streamDcId.flatMap(Int.init)
|
||||
if let datacenterId = GroupCallInfo(call)?.streamDcId.flatMap(Int.init) {
|
||||
return account.network.download(datacenterId: datacenterId, isMedia: true, tag: nil)
|
||||
|> map { download -> AudioBroadcastDataSource? in
|
||||
return AudioBroadcastDataSource(download: download)
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1921,7 +1936,7 @@ public struct GetAudioBroadcastPartResult {
|
||||
public enum Status {
|
||||
case data(Data)
|
||||
case notReady
|
||||
case tooOld
|
||||
case resyncNeeded
|
||||
case rejoinNeeded
|
||||
}
|
||||
|
||||
@ -1929,8 +1944,18 @@ public struct GetAudioBroadcastPartResult {
|
||||
public var responseTimestamp: Double
|
||||
}
|
||||
|
||||
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), timeMs: Int64(timestampId) * 1000, scale: 0), offset: 0, limit: 128 * 1024), tag: nil, continueInBackground: false, automaticFloodWait: false)
|
||||
public func getAudioBroadcastPart(dataSource: AudioBroadcastDataSource, callId: Int64, accessHash: Int64, timestampIdMilliseconds: Int64, durationMilliseconds: Int64) -> Signal<GetAudioBroadcastPartResult, NoError> {
|
||||
let scale: Int32
|
||||
switch durationMilliseconds {
|
||||
case 1000:
|
||||
scale = 0
|
||||
case 500:
|
||||
scale = 1
|
||||
default:
|
||||
return .single(GetAudioBroadcastPartResult(status: .notReady, responseTimestamp: Double(timestampIdMilliseconds) / 1000.0))
|
||||
}
|
||||
|
||||
return dataSource.download.requestWithAdditionalData(Api.functions.upload.getFile(flags: 0, location: .inputGroupCallStream(call: .inputGroupCall(id: callId, accessHash: accessHash), timeMs: timestampIdMilliseconds, scale: scale), offset: 0, limit: 128 * 1024), automaticFloodWait: false, failOnServerErrors: true)
|
||||
|> map { result, responseTimestamp -> GetAudioBroadcastPartResult in
|
||||
switch result {
|
||||
case let .file(_, _, bytes):
|
||||
@ -1956,14 +1981,14 @@ public func getAudioBroadcastPart(account: Account, callId: Int64, accessHash: I
|
||||
status: .notReady,
|
||||
responseTimestamp: responseTimestamp
|
||||
))
|
||||
} else if error.errorDescription == "DATE_INVALID" {
|
||||
} else if error.errorDescription == "TIME_INVALID" || error.errorDescription == "TIME_TOO_SMALL" || error.errorDescription == "TIME_TOO_BIG" {
|
||||
return .single(GetAudioBroadcastPartResult(
|
||||
status: .tooOld,
|
||||
status: .resyncNeeded,
|
||||
responseTimestamp: responseTimestamp
|
||||
))
|
||||
} else {
|
||||
return .single(GetAudioBroadcastPartResult(
|
||||
status: .notReady,
|
||||
status: .resyncNeeded,
|
||||
responseTimestamp: responseTimestamp
|
||||
))
|
||||
}
|
||||
|
@ -14,9 +14,6 @@ swift_library(
|
||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||
"//submodules/TgVoip:TgVoip",
|
||||
"//submodules/TgVoipWebrtc:TgVoipWebrtc",
|
||||
"//submodules/MediaPlayer:UniversalMediaPlayer",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/OpusBinding:OpusBinding",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -1,9 +1,6 @@
|
||||
import Foundation
|
||||
import SwiftSignalKit
|
||||
import TgVoipWebrtc
|
||||
//import UniversalMediaPlayer
|
||||
//import AppBundle
|
||||
import OpusBinding
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
|
||||
@ -32,7 +29,7 @@ private final class ContextQueueImpl: NSObject, OngoingCallThreadLocalContextQue
|
||||
}
|
||||
|
||||
private protocol BroadcastPartSource: class {
|
||||
func requestPart(timestamp: Int32, completion: @escaping (OngoingGroupCallBroadcastPart) -> Void, rejoinNeeded: @escaping () -> Void) -> Disposable
|
||||
func requestPart(timestampMilliseconds: Int64, durationMilliseconds: Int64, completion: @escaping (OngoingGroupCallBroadcastPart) -> Void, rejoinNeeded: @escaping () -> Void) -> Disposable
|
||||
}
|
||||
|
||||
private final class NetworkBroadcastPartSource: BroadcastPartSource {
|
||||
@ -40,29 +37,28 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource {
|
||||
private let account: Account
|
||||
private let callId: Int64
|
||||
private let accessHash: Int64
|
||||
private var datacenterId: Int?
|
||||
private var dataSource: AudioBroadcastDataSource?
|
||||
|
||||
private let dumpDir: TempBoxDirectory
|
||||
|
||||
init(queue: Queue, account: Account, callId: Int64, accessHash: Int64, datacenterId: Int?) {
|
||||
init(queue: Queue, account: Account, callId: Int64, accessHash: Int64) {
|
||||
self.queue = queue
|
||||
self.account = account
|
||||
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 {
|
||||
let timestampId = timestamp == 0 ? Int32(Date().timeIntervalSince1970) : timestamp
|
||||
|
||||
let datacenterId: Signal<Int?, NoError>
|
||||
if let datacenterIdValue = self.datacenterId {
|
||||
datacenterId = .single(datacenterIdValue)
|
||||
func requestPart(timestampMilliseconds: Int64, durationMilliseconds: Int64, completion: @escaping (OngoingGroupCallBroadcastPart) -> Void, rejoinNeeded: @escaping () -> Void) -> Disposable {
|
||||
let timestampIdMilliseconds: Int64
|
||||
if timestampMilliseconds != 0 {
|
||||
timestampIdMilliseconds = timestampMilliseconds
|
||||
} else {
|
||||
datacenterId = getAudioBroadcastDatacenter(account: self.account, callId: self.callId, accessHash: self.accessHash)
|
||||
timestampIdMilliseconds = (Int64(Date().timeIntervalSince1970 * 1000.0) / durationMilliseconds) * durationMilliseconds
|
||||
}
|
||||
|
||||
let dataSource: Signal<AudioBroadcastDataSource?, NoError>
|
||||
if let dataSourceValue = self.dataSource {
|
||||
dataSource = .single(dataSourceValue)
|
||||
} else {
|
||||
dataSource = getAudioBroadcastDataSource(account: self.account, callId: self.callId, accessHash: self.accessHash)
|
||||
}
|
||||
|
||||
let account = self.account
|
||||
@ -70,12 +66,12 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource {
|
||||
let accessHash = self.accessHash
|
||||
|
||||
let queue = self.queue
|
||||
let signal = datacenterId
|
||||
let signal = dataSource
|
||||
|> deliverOn(self.queue)
|
||||
|> mapToSignal { [weak self] datacenterId -> Signal<GetAudioBroadcastPartResult?, NoError> in
|
||||
if let datacenterId = datacenterId {
|
||||
self?.datacenterId = datacenterId
|
||||
return getAudioBroadcastPart(account: account, callId: callId, accessHash: accessHash, datacenterId: datacenterId, timestampId: timestampId)
|
||||
|> mapToSignal { [weak self] dataSource -> Signal<GetAudioBroadcastPartResult?, NoError> in
|
||||
if let dataSource = dataSource {
|
||||
self?.dataSource = dataSource
|
||||
return getAudioBroadcastPart(dataSource: dataSource, callId: callId, accessHash: accessHash, timestampIdMilliseconds: timestampIdMilliseconds, durationMilliseconds: durationMilliseconds)
|
||||
|> map(Optional.init)
|
||||
} else {
|
||||
return .single(nil)
|
||||
@ -83,25 +79,20 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource {
|
||||
}
|
||||
}
|
||||
|> deliverOn(self.queue)
|
||||
|
||||
let dumpDir = self.dumpDir
|
||||
|
||||
return signal.start(next: { result in
|
||||
guard let result = result else {
|
||||
completion(OngoingGroupCallBroadcastPart(timestamp: timestampId, responseTimestamp: Double(timestampId), status: .notReady, oggData: Data()))
|
||||
completion(OngoingGroupCallBroadcastPart(timestampMilliseconds: timestampIdMilliseconds, responseTimestamp: Double(timestampIdMilliseconds), status: .notReady, oggData: Data()))
|
||||
return
|
||||
}
|
||||
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)
|
||||
part = OngoingGroupCallBroadcastPart(timestampMilliseconds: timestampIdMilliseconds, responseTimestamp: result.responseTimestamp, status: .success, oggData: dataValue)
|
||||
case .notReady:
|
||||
part = OngoingGroupCallBroadcastPart(timestamp: timestampId, responseTimestamp: result.responseTimestamp, status: .notReady, oggData: Data())
|
||||
case .tooOld:
|
||||
part = OngoingGroupCallBroadcastPart(timestamp: timestampId, responseTimestamp: result.responseTimestamp, status: .tooOld, oggData: Data())
|
||||
part = OngoingGroupCallBroadcastPart(timestampMilliseconds: timestampIdMilliseconds, responseTimestamp: result.responseTimestamp, status: .notReady, oggData: Data())
|
||||
case .resyncNeeded:
|
||||
part = OngoingGroupCallBroadcastPart(timestampMilliseconds: timestampIdMilliseconds, responseTimestamp: result.responseTimestamp, status: .resyncNeeded, oggData: Data())
|
||||
case .rejoinNeeded:
|
||||
rejoinNeeded()
|
||||
return
|
||||
@ -129,13 +120,11 @@ public final class OngoingGroupCallContext {
|
||||
public var account: Account
|
||||
public var callId: Int64
|
||||
public var accessHash: Int64
|
||||
public var datacenterId: Int?
|
||||
|
||||
public init(account: Account, callId: Int64, accessHash: Int64, datacenterId: Int?) {
|
||||
public init(account: Account, callId: Int64, accessHash: Int64) {
|
||||
self.account = account
|
||||
self.callId = callId
|
||||
self.accessHash = accessHash
|
||||
self.datacenterId = datacenterId
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +166,7 @@ public final class OngoingGroupCallContext {
|
||||
var audioLevelsUpdatedImpl: (([NSNumber]) -> Void)?
|
||||
|
||||
if let audioStreamData = audioStreamData {
|
||||
let broadcastPartsSource = NetworkBroadcastPartSource(queue: queue, account: audioStreamData.account, callId: audioStreamData.callId, accessHash: audioStreamData.accessHash, datacenterId: audioStreamData.datacenterId)
|
||||
let broadcastPartsSource = NetworkBroadcastPartSource(queue: queue, account: audioStreamData.account, callId: audioStreamData.callId, accessHash: audioStreamData.accessHash)
|
||||
self.broadcastPartsSource = broadcastPartsSource
|
||||
}
|
||||
|
||||
@ -201,11 +190,11 @@ public final class OngoingGroupCallContext {
|
||||
participantDescriptionsRequired: { ssrcs in
|
||||
participantDescriptionsRequired(Set(ssrcs.map { $0.uint32Value }))
|
||||
},
|
||||
requestBroadcastPart: { timestamp, completion in
|
||||
requestBroadcastPart: { timestampMilliseconds, durationMilliseconds, completion in
|
||||
let disposable = MetaDisposable()
|
||||
|
||||
queue.async {
|
||||
disposable.set(broadcastPartsSource?.requestPart(timestamp: timestamp, completion: completion, rejoinNeeded: {
|
||||
disposable.set(broadcastPartsSource?.requestPart(timestampMilliseconds: timestampMilliseconds, durationMilliseconds: durationMilliseconds, completion: completion, rejoinNeeded: {
|
||||
rejoinNeeded()
|
||||
}))
|
||||
}
|
||||
|
@ -180,23 +180,23 @@ typedef NS_ENUM(int32_t, OngoingCallConnectionMode) {
|
||||
typedef NS_ENUM(int32_t, OngoingGroupCallBroadcastPartStatus) {
|
||||
OngoingGroupCallBroadcastPartStatusSuccess,
|
||||
OngoingGroupCallBroadcastPartStatusNotReady,
|
||||
OngoingGroupCallBroadcastPartStatusTooOld
|
||||
OngoingGroupCallBroadcastPartStatusResyncNeeded
|
||||
};
|
||||
|
||||
@interface OngoingGroupCallBroadcastPart : NSObject
|
||||
|
||||
@property (nonatomic, readonly) int32_t timestamp;
|
||||
@property (nonatomic, readonly) int64_t timestampMilliseconds;
|
||||
@property (nonatomic, readonly) double responseTimestamp;
|
||||
@property (nonatomic, readonly) OngoingGroupCallBroadcastPartStatus status;
|
||||
@property (nonatomic, strong, readonly) NSData * _Nonnull oggData;
|
||||
|
||||
- (instancetype _Nonnull)initWithTimestamp:(int32_t)timestamp responseTimestamp:(double)responseTimestamp status:(OngoingGroupCallBroadcastPartStatus)status oggData:(NSData * _Nonnull)oggData;
|
||||
- (instancetype _Nonnull)initWithTimestampMilliseconds:(int64_t)timestampMilliseconds responseTimestamp:(double)responseTimestamp status:(OngoingGroupCallBroadcastPartStatus)status oggData:(NSData * _Nonnull)oggData;
|
||||
|
||||
@end
|
||||
|
||||
@interface GroupCallThreadLocalContext : NSObject
|
||||
|
||||
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int32_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart;
|
||||
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart;
|
||||
|
||||
- (void)stop;
|
||||
|
||||
|
@ -426,8 +426,8 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
|
||||
.enableNS = true,
|
||||
.enableAGC = true,
|
||||
.enableCallUpgrade = false,
|
||||
.logPath = logPath.length == 0 ? "" : std::string(logPath.UTF8String),
|
||||
.statsLogPath = statsLogPath.length == 0 ? "" : std::string(statsLogPath.UTF8String),
|
||||
.logPath = std::string(logPath.length == 0 ? "" : logPath.UTF8String),
|
||||
.statsLogPath = std::string(statsLogPath.length == 0 ? "" : statsLogPath.UTF8String),
|
||||
.maxApiLayer = [OngoingCallThreadLocalContextWebrtc maxLayer],
|
||||
.enableHighBitrateVideo = true,
|
||||
.preferredVideoCodecs = preferredVideoCodecs,
|
||||
@ -853,7 +853,7 @@ private:
|
||||
|
||||
@implementation GroupCallThreadLocalContext
|
||||
|
||||
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int32_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart {
|
||||
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = queue;
|
||||
@ -898,10 +898,10 @@ private:
|
||||
}
|
||||
participantDescriptionsRequired(mappedSources);
|
||||
},
|
||||
.requestBroadcastPart = [requestBroadcastPart](int32_t timestamp, std::function<void(tgcalls::BroadcastPart &&)> completion) -> std::shared_ptr<tgcalls::BroadcastPartTask> {
|
||||
id<OngoingGroupCallBroadcastPartTask> task = requestBroadcastPart(timestamp, ^(OngoingGroupCallBroadcastPart * _Nullable part) {
|
||||
.requestBroadcastPart = [requestBroadcastPart](int64_t timestampMilliseconds, int64_t durationMilliseconds, std::function<void(tgcalls::BroadcastPart &&)> completion) -> std::shared_ptr<tgcalls::BroadcastPartTask> {
|
||||
id<OngoingGroupCallBroadcastPartTask> task = requestBroadcastPart(timestampMilliseconds, durationMilliseconds, ^(OngoingGroupCallBroadcastPart * _Nullable part) {
|
||||
tgcalls::BroadcastPart parsedPart;
|
||||
parsedPart.timestamp = part.timestamp;
|
||||
parsedPart.timestampMilliseconds = part.timestampMilliseconds;
|
||||
|
||||
parsedPart.responseTimestamp = part.responseTimestamp;
|
||||
|
||||
@ -915,8 +915,8 @@ private:
|
||||
mappedStatus = tgcalls::BroadcastPart::Status::NotReady;
|
||||
break;
|
||||
}
|
||||
case OngoingGroupCallBroadcastPartStatusTooOld: {
|
||||
mappedStatus = tgcalls::BroadcastPart::Status::TooOld;
|
||||
case OngoingGroupCallBroadcastPartStatusResyncNeeded: {
|
||||
mappedStatus = tgcalls::BroadcastPart::Status::ResyncNeeded;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -1495,10 +1495,10 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
|
||||
|
||||
@implementation OngoingGroupCallBroadcastPart
|
||||
|
||||
- (instancetype _Nonnull)initWithTimestamp:(int32_t)timestamp responseTimestamp:(double)responseTimestamp status:(OngoingGroupCallBroadcastPartStatus)status oggData:(NSData * _Nonnull)oggData {
|
||||
- (instancetype _Nonnull)initWithTimestampMilliseconds:(int64_t)timestampMilliseconds responseTimestamp:(double)responseTimestamp status:(OngoingGroupCallBroadcastPartStatus)status oggData:(NSData * _Nonnull)oggData {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_timestamp = timestamp;
|
||||
_timestampMilliseconds = timestampMilliseconds;
|
||||
_responseTimestamp = responseTimestamp;
|
||||
_status = status;
|
||||
_oggData = oggData;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 43bd0ee8b629939e5bc05eae34b0f17e3263b3b3
|
||||
Subproject commit 18ed939bf6818139f7147cde1c34cf22eb5080a2
|
Loading…
x
Reference in New Issue
Block a user