rtmp、rtc推拉流支持加密

This commit is contained in:
caleb
2026-04-07 16:35:04 +08:00
parent bc56b7851d
commit 88800334ec
19 changed files with 370 additions and 147 deletions

View File

@@ -13,9 +13,7 @@
#import "AVLiveStreamModel.h"
#import "AVLiveStreamCell.h"
#import "SCPlayerConfigView.h"
#import <AFNetworking/AFNetworking.h>
#import <AFNetworking/UIImageView+AFNetworking.h>
#import <YYModel/YYModel.h>
#import "AVApiService.h"
@interface AVHomeViewController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) UIView *headerView;
@@ -23,13 +21,11 @@
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSArray<AVLiveStreamModel *> *liveStreams;
@property (nonatomic, strong) UIRefreshControl *refreshControl;
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
@end
@implementation AVHomeViewController
static NSString * const kLiveStreamCellIdentifier = @"LiveStreamCell";
static NSString * const kLiveListAPIURL = @"http://rtmp.sellycloud.io:8089/live/sdk/alive-list";
- (void)viewDidLoad {
[super viewDidLoad];
@@ -53,11 +49,6 @@ static NSString * const kLiveListAPIURL = @"http://rtmp.sellycloud.io:8089/live/
//
self.liveStreams = [NSMutableArray array];
// AFNetworking
self.sessionManager = [AFHTTPSessionManager manager];
self.sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
self.sessionManager.requestSerializer.timeoutInterval = 10;
[self setupHeaderButtons];
[self setupCollectionView];
@@ -191,30 +182,20 @@ static NSString * const kLiveListAPIURL = @"http://rtmp.sellycloud.io:8089/live/
- (void)fetchLiveStreams {
__weak typeof(self) weakSelf = self;
[self.sessionManager GET:kLiveListAPIURL parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *responseObject) {
[[AVApiService shared] fetchLiveStreams:^(NSArray<AVLiveStreamModel *> *streams) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) return;
NSLog(@"%@",responseObject);
[strongSelf.refreshControl endRefreshing];
//
strongSelf.liveStreams = [NSArray yy_modelArrayWithClass:AVLiveStreamModel.class json:responseObject[@"list"]];
NSLog(@"✅ 成功获取 %ld 个直播流", (long)strongSelf.liveStreams.count);
// UI
strongSelf.liveStreams = streams;
NSLog(@"✅ 成功获取 %ld 个直播流", (long)streams.count);
[strongSelf.collectionView reloadData];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
} failure:^(NSError *error) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) return;
[strongSelf.refreshControl endRefreshing];
NSLog(@"❌ 网络请求失败: %@", error.localizedDescription);
//
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"加载失败"
message:[NSString stringWithFormat:@"无法获取直播列表: %@", error.localizedDescription]
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
[strongSelf presentViewController:alert animated:YES completion:nil];
@@ -349,6 +330,7 @@ static NSString * const kLiveListAPIURL = @"http://rtmp.sellycloud.io:8089/live/
liveStream.preview_image = @"";
liveStream.duration = 0;
liveStream.startTime = [[NSDate date] timeIntervalSince1970];
liveStream.xorKey = config.xorKey;
// playProtocol
switch (config.protocol) {

View File

@@ -17,6 +17,7 @@
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *liveLabel;
@property (nonatomic, strong) UILabel *protocolLabel;
@property (nonatomic, strong) UIImageView *encryptIcon;
@end
@@ -141,6 +142,19 @@
make.centerY.equalTo(_liveLabel);
make.height.equalTo(@16);
make.width.greaterThanOrEqualTo(@40);
}];
//
_encryptIcon = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"lock.shield.fill"]];
_encryptIcon.tintColor = [UIColor systemOrangeColor];
_encryptIcon.contentMode = UIViewContentModeScaleAspectFit;
_encryptIcon.hidden = YES;
[infoContainerView addSubview:_encryptIcon];
[_encryptIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_protocolLabel.mas_right).offset(6);
make.centerY.equalTo(_liveLabel);
make.width.height.equalTo(@20);
make.right.lessThanOrEqualTo(infoContainerView);
}];
}
@@ -154,6 +168,9 @@
//
_protocolLabel.text = model.play_protocol.uppercaseString;
//
_encryptIcon.hidden = (model.xorKey.length == 0);
// 使 SDWebImage
if (model.preview_image.length > 0) {
@@ -177,6 +194,7 @@
_nameLabel.text = @"";
_durationLabel.text = @"";
_protocolLabel.text = @"";
_encryptIcon.hidden = YES;
}
@end