initial commit

This commit is contained in:
Caleb
2026-03-01 15:59:27 +08:00
commit a9e97d56cb
1426 changed files with 172367 additions and 0 deletions

View File

@@ -0,0 +1,194 @@
//
// SLSVideoTileView.m
// SellyCloudSDK_Example
//
// Created by Caleb on 13/11/25.
// Copyright © 2025 Caleb. All rights reserved.
//
#import "SLSVideoTileView.h"
@interface SLSVideoTileView ()
@property (nonatomic, strong)NSString *userId;
@property (nonatomic, strong) UIView *contentViewInternal;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UIImageView *muteIcon;
@property (nonatomic, strong) UIView *videoMaskView;
@property (nonatomic, strong) UILabel *videoOffLabel;
@property (nonatomic, strong) UILabel *bitrate;
@property (nonatomic, strong) UILabel *fps;
@property (nonatomic, strong) UILabel *codec;
@property (nonatomic, strong) UILabel *rtt;
@end
@implementation SLSVideoTileView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.layer.cornerRadius = 10.f;
self.clipsToBounds = YES;
self.backgroundColor = [UIColor blackColor];
_contentViewInternal = [[UIView alloc] initWithFrame:self.bounds];
_contentViewInternal.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_contentViewInternal.backgroundColor = [UIColor blackColor];
[self addSubview:_contentViewInternal];
_videoMaskView = [[UIView alloc] initWithFrame:self.bounds];
_videoMaskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_videoMaskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
_videoMaskView.hidden = YES;
[self addSubview:_videoMaskView];
_videoOffLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_videoOffLabel.textAlignment = NSTextAlignmentCenter;
_videoOffLabel.textColor = [UIColor lightGrayColor];
_videoOffLabel.font = [UIFont systemFontOfSize:14];
_videoOffLabel.text = @"视频已关闭";
[_videoMaskView addSubview:_videoOffLabel];
_nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_nameLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightMedium];
_nameLabel.textColor = [UIColor whiteColor];
_nameLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
_nameLabel.layer.cornerRadius = 8;
_nameLabel.clipsToBounds = YES;
[self addSubview:_nameLabel];
_muteIcon = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"mic.slash.fill"]];
_muteIcon.tintColor = [UIColor systemRedColor];
[self addSubview:_muteIcon];
[self addSubview:self.bitrate];
[self addSubview:self.fps];
[self addSubview:self.codec];
[self addSubview:self.rtt];
[self.bitrate mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.offset(10);
}];
[self.fps mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.bitrate.mas_bottom).offset(10);
make.left.offset(10);
}];
[self.codec mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.fps.mas_bottom).offset(10);
make.left.offset(10);
}];
[self.rtt mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.codec.mas_bottom).offset(10);
make.left.offset(10);
}];
}
return self;
}
- (UIView *)contentView {
return self.contentViewInternal;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.contentViewInternal.frame = self.bounds;
self.videoMaskView.frame = self.bounds;
self.videoOffLabel.frame = CGRectInset(self.videoMaskView.bounds, 8, 8);
CGFloat padding = 6.f;
CGSize maxSize = CGSizeMake(self.bounds.size.width - 2*padding, 20);
CGSize nameSize = [self.nameLabel sizeThatFits:maxSize];
self.nameLabel.frame = CGRectMake(padding,
self.bounds.size.height - nameSize.height - padding,
nameSize.width + 12,
nameSize.height);
self.muteIcon.frame = CGRectMake(CGRectGetMaxX(self.nameLabel.frame) + 4,
CGRectGetMinY(self.nameLabel.frame) - 2,
18,
18);
}
- (void)updateWithParticipant:(SLSParticipant *)p {
self.userId = p.uid;
//
self.nameLabel.text = p.displayName.length ? p.displayName : p.uid;
//
self.muteIcon.hidden = !p.audioMuted;
// contentView
BOOL videoOn = !p.videoMuted;
self.videoMaskView.hidden = videoOn;
//
if (p.level > 0.25 && !p.audioMuted) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor systemGreenColor].CGColor;
} else {
self.layer.borderWidth = 0.f;
self.layer.borderColor = nil;
}
[self setNeedsLayout];
}
- (void)setStats:(SellyRTCStats *)stats {
_stats = stats;
self.rtt.text = [NSString stringWithFormat:@" rtt%ldms ",(NSInteger)stats.transportRttMs];
self.codec.text = [NSString stringWithFormat:@" %@/%@ ",stats.videoCodec,stats.audioCodec];
if ([self.userId isEqualToString:SellyCloudManager.sharedInstance.userId]) {
self.bitrate.text = [NSString stringWithFormat:@" 码率:%ld kbps ",(NSInteger)(stats.txKbps)];
self.fps.text = [NSString stringWithFormat:@" 视频:%ld fps %ldx%ld ",(NSInteger)(stats.sentFps),(NSInteger)(stats.sentWidth),(NSInteger)(stats.sentHeight)];
}
else {
self.bitrate.text = [NSString stringWithFormat:@" 码率:%ld kbps ",(NSInteger)(stats.rxKbps)];
self.fps.text = [NSString stringWithFormat:@" 视频:%ld fps %ldx%ld ",(NSInteger)(stats.recvFps),(NSInteger)(stats.recvWidth),(NSInteger)(stats.recvHeight)];
}
}
- (UILabel *)bitrate {
if (!_bitrate) {
_bitrate = [self createStatsLabel];
}
return _bitrate;
}
- (UILabel *)fps {
if (!_fps) {
_fps = [self createStatsLabel];
}
return _fps;
}
- (UILabel *)codec {
if (!_codec) {
_codec = [self createStatsLabel];
}
return _codec;
}
- (UILabel *)rtt {
if (!_rtt) {
_rtt = [self createStatsLabel];
}
return _rtt;
}
- (UILabel *)createStatsLabel {
UILabel *label = [[UILabel alloc] init];
label.font = [UIFont systemFontOfSize:12];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.2];
label.textAlignment = NSTextAlignmentLeft;
label.layer.cornerRadius = 4;
label.layer.masksToBounds = YES;
return label;
}
@end