mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-25 17:43:18 +00:00
Video updates
This commit is contained in:
parent
0c046a4af6
commit
e87529152f
@ -572,7 +572,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
|
|
||||||
self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||||
|
|
||||||
|
if accountContext.sharedContext.immediateExperimentalUISettings.demoVideoChats {
|
||||||
self.videoCapturer = OngoingCallVideoCapturer(keepLandscape: false)
|
self.videoCapturer = OngoingCallVideoCapturer(keepLandscape: false)
|
||||||
|
}
|
||||||
self.isVideo = self.videoCapturer != nil
|
self.isVideo = self.videoCapturer != nil
|
||||||
|
|
||||||
var didReceiveAudioOutputs = false
|
var didReceiveAudioOutputs = false
|
||||||
@ -1061,7 +1063,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
strongSelf.requestCall(movingFromBroadcastToRtc: false)
|
strongSelf.requestCall(movingFromBroadcastToRtc: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit)
|
}, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit, enableVideo: self.isVideo)
|
||||||
self.incomingVideoSourcePromise.set(callContext.videoSources
|
self.incomingVideoSourcePromise.set(callContext.videoSources
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> map { [weak self] sources -> [PeerId: UInt32] in
|
|> map { [weak self] sources -> [PeerId: UInt32] in
|
||||||
|
|||||||
@ -268,6 +268,7 @@ private final class MainVideoContainerNode: ASDisplayNode {
|
|||||||
private let call: PresentationGroupCall
|
private let call: PresentationGroupCall
|
||||||
|
|
||||||
private var currentVideoNode: GroupVideoNode?
|
private var currentVideoNode: GroupVideoNode?
|
||||||
|
private var candidateVideoNode: GroupVideoNode?
|
||||||
private var currentPeer: (PeerId, UInt32)?
|
private var currentPeer: (PeerId, UInt32)?
|
||||||
|
|
||||||
private var validLayout: CGSize?
|
private var validLayout: CGSize?
|
||||||
@ -281,7 +282,7 @@ private final class MainVideoContainerNode: ASDisplayNode {
|
|||||||
self.backgroundColor = .black
|
self.backgroundColor = .black
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePeer(peer: (peerId: PeerId, source: UInt32)?) {
|
func updatePeer(peer: (peerId: PeerId, source: UInt32)?, waitForFullSize: Bool) {
|
||||||
if self.currentPeer?.0 == peer?.0 && self.currentPeer?.1 == peer?.1 {
|
if self.currentPeer?.0 == peer?.0 && self.currentPeer?.1 == peer?.1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -292,7 +293,16 @@ private final class MainVideoContainerNode: ASDisplayNode {
|
|||||||
guard let strongSelf = self, let videoView = videoView else {
|
guard let strongSelf = self, let videoView = videoView else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let videoNode = GroupVideoNode(videoView: videoView)
|
|
||||||
|
if waitForFullSize {
|
||||||
|
let candidateVideoNode = GroupVideoNode(videoView: videoView)
|
||||||
|
strongSelf.candidateVideoNode = candidateVideoNode
|
||||||
|
|
||||||
|
Queue.mainQueue().after(0.3, { [weak candidateVideoNode] in
|
||||||
|
guard let strongSelf = self, let videoNode = candidateVideoNode, videoNode === strongSelf.candidateVideoNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let currentVideoNode = strongSelf.currentVideoNode {
|
if let currentVideoNode = strongSelf.currentVideoNode {
|
||||||
currentVideoNode.removeFromSupernode()
|
currentVideoNode.removeFromSupernode()
|
||||||
strongSelf.currentVideoNode = nil
|
strongSelf.currentVideoNode = nil
|
||||||
@ -302,6 +312,22 @@ private final class MainVideoContainerNode: ASDisplayNode {
|
|||||||
if let size = strongSelf.validLayout {
|
if let size = strongSelf.validLayout {
|
||||||
strongSelf.update(size: size, transition: .immediate)
|
strongSelf.update(size: size, transition: .immediate)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
strongSelf.candidateVideoNode = nil
|
||||||
|
|
||||||
|
let videoNode = GroupVideoNode(videoView: videoView)
|
||||||
|
|
||||||
|
if let currentVideoNode = strongSelf.currentVideoNode {
|
||||||
|
currentVideoNode.removeFromSupernode()
|
||||||
|
strongSelf.currentVideoNode = nil
|
||||||
|
}
|
||||||
|
strongSelf.currentVideoNode = videoNode
|
||||||
|
strongSelf.addSubnode(videoNode)
|
||||||
|
if let size = strongSelf.validLayout {
|
||||||
|
strongSelf.update(size: size, transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -874,11 +900,11 @@ public final class VoiceChatController: ViewController {
|
|||||||
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
|
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
|
||||||
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
|
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
|
||||||
strongSelf.call.setFullSizeVideo(peerId: peerId)
|
strongSelf.call.setFullSizeVideo(peerId: peerId)
|
||||||
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source))
|
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source), waitForFullSize: false)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.currentDominantSpeakerWithVideo = nil
|
strongSelf.currentDominantSpeakerWithVideo = nil
|
||||||
strongSelf.call.setFullSizeVideo(peerId: nil)
|
strongSelf.call.setFullSizeVideo(peerId: nil)
|
||||||
strongSelf.mainVideoContainer?.updatePeer(peer: nil)
|
strongSelf.mainVideoContainer?.updatePeer(peer: nil, waitForFullSize: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1557,7 +1583,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
|
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
|
||||||
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
|
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
|
||||||
strongSelf.call.setFullSizeVideo(peerId: peerId)
|
strongSelf.call.setFullSizeVideo(peerId: peerId)
|
||||||
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source))
|
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source), waitForFullSize: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1709,7 +1735,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
if !validSources.contains(source) {
|
if !validSources.contains(source) {
|
||||||
strongSelf.currentDominantSpeakerWithVideo = nil
|
strongSelf.currentDominantSpeakerWithVideo = nil
|
||||||
strongSelf.call.setFullSizeVideo(peerId: nil)
|
strongSelf.call.setFullSizeVideo(peerId: nil)
|
||||||
strongSelf.mainVideoContainer?.updatePeer(peer: nil)
|
strongSelf.mainVideoContainer?.updatePeer(peer: nil, waitForFullSize: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2493,7 +2519,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
let topPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelOffset), size: CGSize(width: size.width, height: topPanelHeight))
|
let topPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelOffset), size: CGSize(width: size.width, height: topPanelHeight))
|
||||||
|
|
||||||
if let mainVideoContainer = self.mainVideoContainer {
|
if let mainVideoContainer = self.mainVideoContainer {
|
||||||
let videoContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: layout.size.width, height: 200.0))
|
let videoContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: layout.size.width, height: min(300.0, layout.size.width)))
|
||||||
transition.updateFrameAdditive(node: mainVideoContainer, frame: videoContainerFrame)
|
transition.updateFrameAdditive(node: mainVideoContainer, frame: videoContainerFrame)
|
||||||
mainVideoContainer.update(size: videoContainerFrame.size, transition: transition)
|
mainVideoContainer.update(size: videoContainerFrame.size, transition: transition)
|
||||||
}
|
}
|
||||||
@ -2764,7 +2790,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
let bottomPanelHeight = bottomAreaHeight + layout.intrinsicInsets.bottom
|
let bottomPanelHeight = bottomAreaHeight + layout.intrinsicInsets.bottom
|
||||||
var listTopInset = layoutTopInset + topPanelHeight
|
var listTopInset = layoutTopInset + topPanelHeight
|
||||||
if self.mainVideoContainer != nil {
|
if self.mainVideoContainer != nil {
|
||||||
listTopInset += 200.0
|
listTopInset += min(300.0, layout.size.width)
|
||||||
}
|
}
|
||||||
let listSize = CGSize(width: size.width, height: layout.size.height - listTopInset - bottomPanelHeight)
|
let listSize = CGSize(width: size.width, height: layout.size.height - listTopInset - bottomPanelHeight)
|
||||||
|
|
||||||
|
|||||||
@ -179,7 +179,7 @@ public final class OngoingGroupCallContext {
|
|||||||
|
|
||||||
private var broadcastPartsSource: BroadcastPartSource?
|
private var broadcastPartsSource: BroadcastPartSource?
|
||||||
|
|
||||||
init(queue: Queue, inputDeviceId: String, outputDeviceId: String, video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?) {
|
init(queue: Queue, inputDeviceId: String, outputDeviceId: String, video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?, enableVideo: Bool) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
|
|
||||||
var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)?
|
var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)?
|
||||||
@ -221,7 +221,8 @@ public final class OngoingGroupCallContext {
|
|||||||
|
|
||||||
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
|
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
|
||||||
},
|
},
|
||||||
outgoingAudioBitrateKbit: outgoingAudioBitrateKbit ?? 32
|
outgoingAudioBitrateKbit: outgoingAudioBitrateKbit ?? 32,
|
||||||
|
enableVideo: enableVideo
|
||||||
)
|
)
|
||||||
|
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
@ -509,10 +510,10 @@ public final class OngoingGroupCallContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(inputDeviceId: String = "", outputDeviceId: String = "", video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?) {
|
public init(inputDeviceId: String = "", outputDeviceId: String = "", video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?, enableVideo: Bool) {
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||||
return Impl(queue: queue, inputDeviceId: inputDeviceId, outputDeviceId: outputDeviceId, video: video, participantDescriptionsRequired: participantDescriptionsRequired, audioStreamData: audioStreamData, rejoinNeeded: rejoinNeeded, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit)
|
return Impl(queue: queue, inputDeviceId: inputDeviceId, outputDeviceId: outputDeviceId, video: video, participantDescriptionsRequired: participantDescriptionsRequired, audioStreamData: audioStreamData, rejoinNeeded: rejoinNeeded, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit, enableVideo: enableVideo)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -196,7 +196,7 @@ typedef NS_ENUM(int32_t, OngoingGroupCallBroadcastPartStatus) {
|
|||||||
|
|
||||||
@interface GroupCallThreadLocalContext : NSObject
|
@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)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit;
|
- (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 outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit enableVideo:(bool)enableVideo;
|
||||||
|
|
||||||
- (void)stop;
|
- (void)stop;
|
||||||
|
|
||||||
|
|||||||
@ -854,7 +854,7 @@ private:
|
|||||||
|
|
||||||
@implementation GroupCallThreadLocalContext
|
@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)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit {
|
- (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 outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit enableVideo:(bool)enableVideo {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_queue = queue;
|
_queue = queue;
|
||||||
@ -938,7 +938,8 @@ private:
|
|||||||
});
|
});
|
||||||
return std::make_shared<BroadcastPartTaskImpl>(task);
|
return std::make_shared<BroadcastPartTaskImpl>(task);
|
||||||
},
|
},
|
||||||
.outgoingAudioBitrateKbit = outgoingAudioBitrateKbit
|
.outgoingAudioBitrateKbit = outgoingAudioBitrateKbit,
|
||||||
|
.enableVideo = enableVideo
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@ -1234,6 +1235,22 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
|
|||||||
parsedParticipants.push_back(parsedParticipant);
|
parsedParticipants.push_back(parsedParticipant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSDictionary *video = dict[@"video"];
|
||||||
|
if ([video isKindOfClass:[NSDictionary class]]) {
|
||||||
|
NSArray *serverSources = video[@"server_sources"];
|
||||||
|
if ([serverSources isKindOfClass:[NSArray class]]) {
|
||||||
|
for (NSNumber *sourceNumber in serverSources) {
|
||||||
|
if ([sourceNumber isKindOfClass:[NSNumber class]]) {
|
||||||
|
int32_t signedSource = [sourceNumber intValue];
|
||||||
|
result.serverVideoBandwidthProbingSsrc = *(int32_t *)&signedSource;
|
||||||
|
} else if ([sourceNumber isKindOfClass:[NSString class]]) {
|
||||||
|
uint32_t source = (uint32_t)[sourceNumber longLongValue];
|
||||||
|
result.serverVideoBandwidthProbingSsrc = source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
_instance->setJoinResponsePayload(result, std::move(parsedParticipants));
|
_instance->setJoinResponsePayload(result, std::move(parsedParticipants));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit e1f6cdaf2cefc1a760d74c1de76568a7557c63be
|
Subproject commit 68ade13752f14fecf0b32bc08e8e47164ef52ddc
|
||||||
Loading…
x
Reference in New Issue
Block a user