From ab52ad98f3a77dab878a02ad4142ada74b67ccb4 Mon Sep 17 00:00:00 2001 From: adamsfliu Date: Thu, 1 Aug 2024 13:05:34 +0800 Subject: [PATCH] [iOS] update version to relesse-12.0.0.6067 --- MLVB-API-Example-OC/.gitignore | 3 +- .../CustomVideoCaptureViewController.m | 10 - .../HlsAutoBitrateViewController.m | 8 - .../LebAutoBitrateViewController.m | 10 - .../NewTimeShiftSpriteViewController.h | 17 + .../NewTimeShiftSpriteViewController.m | 134 ++++++ .../NewTimeShiftSpriteViewController.xib | 152 +++++++ .../NewTimeShiftSprite/TXSpriteImageFetcher.h | 38 ++ .../NewTimeShiftSprite/TXSpriteImageFetcher.m | 400 ++++++++++++++++++ .../PictureInPictureViewController.m | 15 +- .../RTCPushAndPlayAnchorViewController.m | 10 - .../RTCPushAndPlayAudienceViewController.m | 11 - .../ThirdBeautyFaceunityViewController.m | 13 - .../ThirdBeautyTencentEffectViewController.m | 12 +- .../Advanced/TimeShiftPlay/TimeShiftHelper.h | 2 +- .../Advanced/TimeShiftPlay/TimeShiftHelper.m | 2 +- .../TimeShiftPlay/TimeShiftViewController.m | 30 +- MLVB-API-Example-OC/App/Common/URLUtils.m | 4 +- MLVB-API-Example-OC/App/Home/ViewController.m | 5 + .../Basic/LebPlay/LebPlayViewController.m | 8 - .../LiveLink/LiveInputBaseViewController.h | 2 +- .../LiveLink/LiveLinkAnchorViewController.m | 11 - .../LiveLink/LiveLinkAudienceViewController.m | 13 - .../LiveLinkUserInputViewController.h | 2 +- .../Basic/LivePK/LivePkAnchorViewController.m | 13 - .../LivePK/LivePkUserInputViewController.h | 2 +- .../Basic/LivePlay/LivePlayViewController.m | 10 - .../LivePushCameraViewController.m | 10 - .../LivePushScreenViewController.m | 10 - .../Debug/GenerateTestUserSig.h | 82 +--- .../Debug/GenerateTestUserSig.m | 2 +- .../project.pbxproj | 32 +- .../{README.cn.md => README-zh_CN.md} | 6 +- MLVB-API-Example-OC/README.md | 6 +- .../Localized/en.lproj/Localized.strings | 1 + .../Localized/zh-Hans.lproj/Localized.strings | 1 + 36 files changed, 824 insertions(+), 263 deletions(-) create mode 100644 MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.h create mode 100644 MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.m create mode 100644 MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.xib create mode 100644 MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.h create mode 100644 MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.m rename MLVB-API-Example-OC/{README.cn.md => README-zh_CN.md} (91%) diff --git a/MLVB-API-Example-OC/.gitignore b/MLVB-API-Example-OC/.gitignore index ee0bb54..3d1945e 100644 --- a/MLVB-API-Example-OC/.gitignore +++ b/MLVB-API-Example-OC/.gitignore @@ -1,2 +1,3 @@ Advanced/ThirdBeauty/FaceUnity -Advanced/ThirdBeauty/FaceUnity-SDK-iOS-v7.4.0 \ No newline at end of file +Advanced/ThirdBeauty/FaceUnity-SDK-iOS-v7.4.0 +.DS_Store \ No newline at end of file diff --git a/MLVB-API-Example-OC/Advanced/CustomVideoCapture/CustomVideoCaptureViewController.m b/MLVB-API-Example-OC/Advanced/CustomVideoCapture/CustomVideoCaptureViewController.m index bba4a7e..3da531d 100644 --- a/MLVB-API-Example-OC/Advanced/CustomVideoCapture/CustomVideoCaptureViewController.m +++ b/MLVB-API-Example-OC/Advanced/CustomVideoCapture/CustomVideoCaptureViewController.m @@ -6,16 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* -自定义视频采集 - MLVB APP 自定义视频采集功能 - 本文件展示如何集成自定义视频采集功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、开启自定义采集 API: [self.livePusher enableCustomVideoCapture:true]; - 3、开始推流 API:[self.livePusher startPush:[LiveUrl generateTRTCPushUrl:streamId]]; - 4、发送数据 API: [self.livePusher sendCustomVideoFrame:videoFrame]; - 参考文档:https://cloud.tencent.com/document/product/454/56601 - */ /* Custom Video Capturing Custom Video Capturing in MLVB App diff --git a/MLVB-API-Example-OC/Advanced/HlsAutoBitrate/HlsAutoBitrateViewController.m b/MLVB-API-Example-OC/Advanced/HlsAutoBitrate/HlsAutoBitrateViewController.m index c3d7dad..dc97722 100644 --- a/MLVB-API-Example-OC/Advanced/HlsAutoBitrate/HlsAutoBitrateViewController.m +++ b/MLVB-API-Example-OC/Advanced/HlsAutoBitrate/HlsAutoBitrateViewController.m @@ -1,13 +1,5 @@ // Copyright © 2022 Tencent. All rights reserved. /* -HLS自适应码率播放 - MLVB APP 快直播自适应码率播放功能 - 本文件展示如何集成快直播自适应码率播放功能 - 1、设置渲染画面 API:[self.livePlayer setRenderView:self.view]; - 2、开始播放 API: [self.livePlayer startLivePlay:url]; - 参考文档:https://cloud.tencent.com/document/product/454/81211 - */ -/* HLS Auto Bitrate MLVB APP HLS Auto Bitrate 1、Set Render View API:[self.livePlayer setRenderView:self.view]; diff --git a/MLVB-API-Example-OC/Advanced/LebAutoBitrate/LebAutoBitrateViewController.m b/MLVB-API-Example-OC/Advanced/LebAutoBitrate/LebAutoBitrateViewController.m index 87f2292..9216174 100644 --- a/MLVB-API-Example-OC/Advanced/LebAutoBitrate/LebAutoBitrateViewController.m +++ b/MLVB-API-Example-OC/Advanced/LebAutoBitrate/LebAutoBitrateViewController.m @@ -1,15 +1,5 @@ // Copyright © 2022 Tencent. All rights reserved. /* -快直播自适应码率播放 - MLVB APP 快直播自适应码率播放功能 - 本文件展示如何集成快直播自适应码率播放功能 - 1、设置渲染画面 API:[self.livePlayer setRenderView:self.view]; - 2、开始播放 API: [self.livePlayer startLivePlay:url]; - 参考文档:https://cloud.tencent.com/document/product/454/81212 - 开始自适应码率播放后,就无法进行进行无缝切流了。如果在播放状态进入自适应码率, - 需要先停止当前播放,然后再开始自适应播放 - */ -/* Webrtc Auto Bitrate MLVB APP Webrtc Auto Bitrate 1、Set Render View API:[self.livePlayer setRenderView:self.view]; diff --git a/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.h b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.h new file mode 100644 index 0000000..1ab39eb --- /dev/null +++ b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.h @@ -0,0 +1,17 @@ +// +// NewTimeShiftSpriteViewController.h +// MLVB-API-Example-OC +// +// Created by carol on 2024/04/22. +// Copyright © 2024 Tencent. All rights reserved. +// + +#import "ViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NewTimeShiftSpriteViewController : ViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.m b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.m new file mode 100644 index 0000000..b44f61b --- /dev/null +++ b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.m @@ -0,0 +1,134 @@ +// +// NewTimeShiftSpriteViewController.m +// MLVB-API-Example-OC +// +// Created by carol on 2024/04/22. +// Copyright © 2024 Tencent. All rights reserved. +// + +#import "NewTimeShiftSpriteViewController.h" +#import "TXSpriteImageFetcher.h" + +static NSString *const G_NEW_TIME_SHIFT_DOMAIN = @"5000.liveplay.myqcloud.com"; +static NSString *const G_NEW_TIME_SHIFT_PATH = @"live"; +static NSString *const G_NEW_TIME_SHIFT_STREAMID = @"5000_testsprite"; + +@interface NewTimeShiftSpriteViewController () + +@property(weak, nonatomic) IBOutlet UITextField *playDomain; +@property(weak, nonatomic) IBOutlet UITextField *playPath; +@property(weak, nonatomic) IBOutlet UITextField *streamId; +@property(weak, nonatomic) IBOutlet UIDatePicker *startTimePick; +@property(weak, nonatomic) IBOutlet UIDatePicker *endTimePick; +@property(weak, nonatomic) IBOutlet UITextField *playOffsetHh; +@property(weak, nonatomic) IBOutlet UITextField *playOffsetMm; +@property(weak, nonatomic) IBOutlet UITextField *playOffsetSs; +@property(weak, nonatomic) IBOutlet UIButton *btnShowSprite; +@property(weak, nonatomic) IBOutlet UIImageView *spriteImage; + +@property(nonatomic, strong) TXSpriteImageFetcher *spriteImageFetcher; + +@end + +@implementation NewTimeShiftSpriteViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = localize(@"MLVB-API-Example.Home.NewTimeShiftSprite"); + self.view.backgroundColor = UIColor.blackColor; + [self initView]; + [self addKeyboardObserver]; +} + +- (void)initView { + self.playDomain.text = G_NEW_TIME_SHIFT_DOMAIN; + self.playPath.text = G_NEW_TIME_SHIFT_PATH; + self.streamId.text = G_NEW_TIME_SHIFT_STREAMID; + NSDate *currentDate = [NSDate date]; + NSDate *oneHourLater = [currentDate dateByAddingTimeInterval:3600]; // 3600秒表示一小时 + [self.startTimePick setDate:currentDate]; + [self.endTimePick setDate:oneHourLater]; +} + +- (void)dealloc { + [self removeKeyboardObserver]; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self.view endEditing:true]; +} + +- (IBAction)onBtnShowSpriteClick:(id)sender { + [self.spriteImage setImage:nil]; + if (self.spriteImageFetcher == nil) { + self.spriteImageFetcher = [[TXSpriteImageFetcher alloc] init]; + [self.spriteImageFetcher setDelegate:self]; + [self.spriteImageFetcher setCacheSize:10]; + [self.spriteImageFetcher init:self.playDomain.text + path:self.playPath.text + streamId:self.streamId.text + startTs:(long)[self.startTimePick.date timeIntervalSince1970] + endTs:(long)[self.endTimePick.date timeIntervalSince1970]]; + } + long time = 3600 * [self.playOffsetHh.text intValue] + 60 * [self.playOffsetMm.text intValue] + + [self.playOffsetSs.text intValue]; + [self.spriteImageFetcher getThumbnail:time]; +} + +#pragma mark - TXSpriteImageFetcherDelegate +- (void)onFetchDone:(SpriteThumbnailFetchErrCode)errCode image:(UIImage *)image { + if (errCode != SPRITE_THUMBNAIL_FETCH_SUCC) { + NSString *msg = [NSString stringWithFormat:@"onFetchDone errCode is %ld", (long)errCode]; + UIAlertController *alert = + [UIAlertController alertControllerWithTitle:@"提示" + message:msg + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"确定" + style:UIAlertActionStyleDefault + handler:nil]]; + // 弹出提示框 + [self presentViewController:alert animated:YES completion:nil]; + } else { + [self.spriteImage setImage:image]; + } +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + return YES; +} + +#pragma mark - Notification + +- (void)addKeyboardObserver { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (void)removeKeyboardObserver { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (BOOL)keyboardWillShow:(NSNotification *)noti { + return YES; +} + +- (BOOL)keyboardWillHide:(NSNotification *)noti { + return YES; +} + +@end diff --git a/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.xib b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.xib new file mode 100644 index 0000000..78bc620 --- /dev/null +++ b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/NewTimeShiftSpriteViewController.xib @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.h b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.h new file mode 100644 index 0000000..69979f4 --- /dev/null +++ b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.h @@ -0,0 +1,38 @@ +// +// TXSpriteImageFetcher.h +// MLVB-API-Example-OC +// +// Created by carol on 2024/04/22. +// Copyright © 2024 Tencent. All rights reserved. +// + +#import + +typedef NS_ENUM(NSInteger, SpriteThumbnailFetchErrCode) { + SPRITE_THUMBNAIL_FETCH_SUCC = 0, + SPRITE_THUMBNAIL_FETCH_PARAM_INVALID = -1, + SPRITE_THUMBNAIL_FETCH_NETWORK_ERR = -2, + SPRITE_THUMBNAIL_FETCH_SERVER_ERROR = -3 +}; + +@protocol TXSpriteImageFetcherDelegate +- (void)onFetchDone:(SpriteThumbnailFetchErrCode)errCode image:(UIImage *)image; +@end + +@interface TXSpriteImageFetcher : NSObject + +- (void)init:(NSString *)domain + path:(NSString *)path + streamId:(NSString *)streamId + startTs:(long)startTs + endTs:(long)endTs; + +- (void)setDelegate:(id)delegate; + +- (void)getThumbnail:(long)time; + +- (void)setCacheSize:(NSInteger)size; + +- (void)clear; + +@end diff --git a/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.m b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.m new file mode 100644 index 0000000..bffd50a --- /dev/null +++ b/MLVB-API-Example-OC/Advanced/NewTimeShiftSprite/TXSpriteImageFetcher.m @@ -0,0 +1,400 @@ +// +// TXSpriteImageFetcher.m +// MLVB-API-Example-OC +// +// Created by carol on 2024/04/22. +// Copyright © 2024 Tencent. All rights reserved. +// + +#import "TXSpriteImageFetcher.h" + +static NSString *const CONFIG_URL_FORMAT = + @"http://%@/%@/%@.json?txTimeshift=on&tsFormat=unix&tsSpritemode=1&tsStart=%ld&tsEnd=%ld"; +static NSString *const BIG_IMAGE_URL_FORMAT = @"http://%@%@%ld.jpg?txTimeshift=on"; + +@interface TXSpriteConfigData : NSObject + +@property(nonatomic, assign) long startTime; +@property(nonatomic, assign) long endTime; +@property(nonatomic, assign) double duration; +@property(nonatomic, copy) NSString *path; +@property(nonatomic, assign) int cols; +@property(nonatomic, assign) int rows; +@property(nonatomic, assign) int intervalS; +@property(nonatomic, assign) int height; +@property(nonatomic, assign) int width; + +@end + +@implementation TXSpriteConfigData + +- (instancetype)initWithData:(NSDictionary *)data { + self.startTime = [data[@"start_time"] longValue]; + self.endTime = [data[@"end_time"] longValue]; + self.duration = [data[@"duration"] doubleValue]; + self.path = data[@"path"]; + self.cols = [data[@"cols"] intValue]; + self.rows = [data[@"rows"] intValue]; + self.intervalS = [data[@"interval"] intValue]; + self.height = [data[@"height"] intValue]; + self.width = [data[@"width"] intValue]; + + return self; +} + +- (BOOL)isValid { + return (self.path && self.startTime && self.endTime && self.cols && self.rows && self.intervalS && + self.width && self.height); +} + +@end + +@interface TXSpriteImageFetcher () + +@property(atomic, assign) BOOL isFetchingSpriteConfig; +@property(nonatomic, strong) NSMutableArray *downloadingImageUrls; +@property(nonatomic, strong) NSArray *spriteConfigArray; +@property(nonatomic, strong) NSCache *bigImgCache; +@property(nonatomic, strong) NSCache *smallImgCache; + +@property(nonatomic, copy) NSString *domain; +@property(nonatomic, copy) NSString *path; +@property(nonatomic, copy) NSString *streamId; +@property(nonatomic, assign) long startTs; +@property(nonatomic, assign) long endTs; + +@property(atomic, assign) long fetchingTime; +@property(weak, nonatomic) id delegate; + +@end + +@implementation TXSpriteImageFetcher + +- (void)init:(NSString *)domain + path:(NSString *)path + streamId:(NSString *)streamId + startTs:(long)startTs + endTs:(long)endTs { + self.domain = domain; + self.path = path; + self.streamId = streamId; + self.startTs = startTs; + self.endTs = endTs; + + self.spriteConfigArray = [[NSMutableArray alloc] init]; + self.bigImgCache = [[NSCache alloc] init]; + self.smallImgCache = [[NSCache alloc] init]; + + self.isFetchingSpriteConfig = NO; + [self setCacheSize:30]; +} + +- (void)setDelegate:(id)delegate { + @synchronized(_delegate) { + _delegate = delegate; + } +} + +- (void)getThumbnail:(long)time { + _fetchingTime = time; + + UIImage *smallImage = [self getThumbnailFromSmallImageCache:time]; + if (smallImage != nil) { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SUCC image:smallImage]; + return; + } + + smallImage = [self getThumbnailFromBigImageCache:time]; + if (smallImage != nil) { + [self.smallImgCache setObject:smallImage forKey:@(time)]; + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SUCC image:smallImage]; + return; + } + + if (![self isSpriteConfigDataExist:time]) { + [self fetchSpriteConfig]; + return; + } + + NSString *bigImageUrl = [self getBigImageUrl:time]; + if (bigImageUrl.length > 0) { + [self fetchBigImage:bigImageUrl]; + } else { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_PARAM_INVALID image:nil]; + } +} + +- (void)setCacheSize:(NSInteger)size { + [self.smallImgCache setCountLimit:size]; + [self.bigImgCache setCountLimit:size]; +} + +- (void)clear { + self.domain = nil; + self.path = nil; + self.streamId = nil; + self.startTs = 0; + self.endTs = 0; + + self.isFetchingSpriteConfig = NO; + self.spriteConfigArray = nil; + + [self.bigImgCache removeAllObjects]; + [self.smallImgCache removeAllObjects]; + [self.downloadingImageUrls removeAllObjects]; + _fetchingTime = 0; +} + +- (BOOL)isSpriteConfigDataExist:(long)time { + TXSpriteConfigData *configData = [self getSpriteConfig:time]; + if (configData == nil || ![configData isValid]) { + return NO; + } + return YES; +} + +- (UIImage *)getThumbnailFromSmallImageCache:(long)time { + return [self.smallImgCache objectForKey:@(time)]; +} + +- (UIImage *)getBigImageFromCache:(long)time { + NSString *bigImageUrl = [self getBigImageUrl:time]; + return [self.bigImgCache objectForKey:bigImageUrl]; +} + +- (UIImage *)getThumbnailFromBigImageCache:(long)time { + UIImage *bigImage = [self getBigImageFromCache:time]; + if (bigImage == nil) { + return nil; + } + + TXSpriteConfigData *configData = [self getSpriteConfig:time]; + if (configData == nil || ![configData isValid]) { + return nil; + } + + long relativeOffset = [self getRelativeOffset:time configData:configData]; + if (relativeOffset < 0) { + NSLog(@"getThumbnailFromBigImageCache time[%ld] is invalid, relativeOffset is %ld.", + time, + relativeOffset); + return nil; + } + + CGRect smallImageRect = [self getSmallImageRect:relativeOffset configData:configData]; + UIImage *smallImage = [self cropImg:bigImage smallImageRect:smallImageRect]; + + return smallImage; +} + +- (NSString *)getBigImageUrl:(long)time { + TXSpriteConfigData *configData = [self getSpriteConfig:time]; + if (configData == nil || ![configData isValid]) { + return @""; + } + + long relativeOffset = [self getRelativeOffset:time configData:configData]; + if (relativeOffset < 0) { + NSLog(@"getThumbnail time[%ld] is invalid, relativeOffset is %ld.", time, relativeOffset); + return @""; + } + + long picNo = (relativeOffset / (configData.intervalS * configData.cols * configData.rows)); + return [NSString stringWithFormat:BIG_IMAGE_URL_FORMAT, self.domain, configData.path, picNo]; +} + +- (void)fetchSpriteConfig { + if (_isFetchingSpriteConfig) { + return; + } + _isFetchingSpriteConfig = YES; + + __weak TXSpriteImageFetcher *weak_self = self; + NSString *strUrl = [NSString stringWithFormat:CONFIG_URL_FORMAT, + self.domain, + self.path, + self.streamId, + self.startTs, + self.endTs]; + NSLog(@"fetchSpriteConfig url is %@", strUrl); + NSURL *url = [NSURL URLWithString:strUrl]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request setHTTPMethod:@"GET"]; + NSURLSession *session = [NSURLSession sharedSession]; + NSURLSessionDataTask *dataTask = + [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + __strong TXSpriteImageFetcher *strongSelf = weak_self; + [strongSelf handleFetchSpriteConfigResponse:data response:response error:error]; + }]; + [dataTask resume]; +} + +- (void)handleFetchSpriteConfigResponse:(NSData *)data + response:(NSURLResponse *)response + error:(NSError *)error { + _isFetchingSpriteConfig = NO; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (error) { + NSLog(@"fetchSpriteConfig failed %@", error.localizedDescription); + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_NETWORK_ERR image:nil]; + return; + } + NSLog(@"fetchSpriteConfig response code %ld", httpResponse.statusCode); + if (httpResponse.statusCode != 200 || data == nil) { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SERVER_ERROR image:nil]; + return; + } + [self handleFetchSpriteConfigData:data]; +} + +- (void)handleFetchSpriteConfigData:(NSData *)data { + NSError *jsonError; + NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&jsonError]; + if (jsonError) { + NSLog(@"fetchSpriteConfig response json 解析失败: %@", jsonError.localizedDescription); + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SERVER_ERROR image:nil]; + return; + } + + NSMutableArray *retArray = [[NSMutableArray alloc] init]; + NSLog(@"fetchSpriteConfig response data:%@", jsonArray); + for (NSDictionary *json in jsonArray) { + TXSpriteConfigData *configData = [[TXSpriteConfigData alloc] initWithData:json]; + [retArray addObject:configData]; + } + self.spriteConfigArray = retArray; + + TXSpriteConfigData *configData = [self getSpriteConfig:_fetchingTime]; + if (configData == nil || ![configData isValid]) { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SERVER_ERROR image:nil]; + return; + } + + NSString *bigImageUrl = [self getBigImageUrl:_fetchingTime]; + if (bigImageUrl.length > 0) { + [self fetchBigImage:bigImageUrl]; + } else { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_PARAM_INVALID image:nil]; + } +} + +- (TXSpriteConfigData *)getSpriteConfig:(long)time { + for (TXSpriteConfigData *data in self.spriteConfigArray) { + if (self.startTs + time >= data.startTime && self.startTs + time < data.endTime) { + return data; + } + } + return nil; +} + +- (long)getRelativeOffset:(long)time configData:(TXSpriteConfigData *)configData { + // 计算出相对场次的偏移时间 + long relativeOffset = time; + if (self.startTs < configData.startTime) { + relativeOffset -= (configData.startTime - self.startTs); + } else { + relativeOffset += (self.startTs - configData.startTime); + } + return relativeOffset; +} + +- (void)fetchBigImage:(NSString *)bigImageUrl { + @synchronized(_downloadingImageUrls) { + if ([_downloadingImageUrls containsObject:bigImageUrl]) { + return; + } + [_downloadingImageUrls addObject:bigImageUrl]; + } + + NSLog(@"fetchBigImage url:%@", bigImageUrl); + + __weak TXSpriteImageFetcher *weak_self = self; + NSURLSession *session = [NSURLSession sharedSession]; + NSURL *url = [NSURL URLWithString:bigImageUrl]; + NSURLRequest *imageUrlRequest = [NSURLRequest requestWithURL:url]; + NSURLSessionDataTask *imgTask = [session + dataTaskWithRequest:imageUrlRequest + completionHandler:^( + NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + __strong TXSpriteImageFetcher *strongSelf = weak_self; + [strongSelf handleFetchBigImageResponse:bigImageUrl + data:data + response:response + error:error]; + }]; + // 开始下载 + [imgTask resume]; +} + +- (void)handleFetchBigImageResponse:(NSString *)bigImageUrl + data:(NSData *)data + response:(NSURLResponse *)response + error:(NSError *)error { + @synchronized(_downloadingImageUrls) { + [_downloadingImageUrls removeObject:bigImageUrl]; + } + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (error) { + NSLog(@"fetchBigImage failed %@", error.localizedDescription); + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_NETWORK_ERR image:nil]; + return; + } + NSLog(@"fetchBigImage response code %ld", httpResponse.statusCode); + if (httpResponse.statusCode != 200 || data == nil) { + [self notifyFetchThumbnailResult:SPRITE_THUMBNAIL_FETCH_SERVER_ERROR image:nil]; + return; + } + + UIImage *img = [UIImage imageWithData:data]; + [self.bigImgCache setObject:img forKey:bigImageUrl]; + UIImage *smallImage = [self getThumbnailFromBigImageCache:_fetchingTime]; + [self notifyFetchThumbnailResult:smallImage == nil ? SPRITE_THUMBNAIL_FETCH_SERVER_ERROR : + SPRITE_THUMBNAIL_FETCH_SUCC + image:smallImage]; +} + +- (CGRect)getSmallImageRect:(long)time configData:(TXSpriteConfigData *)configData { + int picOffset = + time % (configData.intervalS * configData.rows * configData.cols) / configData.intervalS; + CGRect rect = CGRectZero; + rect.origin.x = (picOffset % configData.cols) * configData.width; + rect.origin.y = (picOffset / configData.cols) * configData.height; + rect.size.width = configData.width; + rect.size.height = configData.height; + return rect; +} + +- (UIImage *)cropImg:(UIImage *)bigImg smallImageRect:(CGRect)smallImageRect { + if (!bigImg) { + return nil; + } + + CGRect rect = CGRectMake(smallImageRect.origin.x * bigImg.scale, + smallImageRect.origin.y * bigImg.scale, + smallImageRect.size.width * bigImg.scale, + smallImageRect.size.height * bigImg.scale); + + CGImageRef imageRef = CGImageCreateWithImageInRect([bigImg CGImage], rect); + UIImage *result = [UIImage imageWithCGImage:imageRef + scale:bigImg.scale + orientation:bigImg.imageOrientation]; + CGImageRelease(imageRef); + return result; +} + +- (void)notifyFetchThumbnailResult:(SpriteThumbnailFetchErrCode)code image:(UIImage *)image { + NSLog(@"notifyFetchThumbnailResult errCode is %ld", code); + @synchronized(self) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (self->_delegate != nil && + [self->_delegate respondsToSelector:@selector(onFetchDone:image:)]) { + [self->_delegate onFetchDone:code image:image]; + } + }); + } +} + +@end diff --git a/MLVB-API-Example-OC/Advanced/PictureInPicture/PictureInPictureViewController.m b/MLVB-API-Example-OC/Advanced/PictureInPicture/PictureInPictureViewController.m index 0f849db..5907f4d 100644 --- a/MLVB-API-Example-OC/Advanced/PictureInPicture/PictureInPictureViewController.m +++ b/MLVB-API-Example-OC/Advanced/PictureInPicture/PictureInPictureViewController.m @@ -10,18 +10,6 @@ #import #import "PictureInPictureView.h" -/* - 画中画功能(iOS15及以上支持) - MLVB APP 画中画功能代码示例: - 本文件展示如何通过移动直播SDK实现iOS系统上的画中画功能 - 1、开启自定义渲染 API:[self.livePlayer enableObserveVideoFrame:YES pixelFormat:V2TXLivePixelFormatNV12 bufferType:V2TXLiveBufferTypePixelBuffer]; - 2、需要开启SDK的后台解码能力 API:[_livePlayer setProperty:@"enableBackgroundDecoding" value:@(YES)]; - 3、使用系统 API创建画中画内容源: AVPictureInPictureControllerContentSource *contentSource = [[AVPictureInPictureControllerContentSource alloc] initWithSampleBufferDisplayLayer:self.sampleBufferDisplayLayer playbackDelegate:self]; - 4、使用系统 API创建画中画控制器: [[AVPictureInPictureController alloc] initWithContentSource:contentSource]; - 5、在SDK回调:- (void)onRenderVideoFrame:(id)player frame:(V2TXLiveVideoFrame *)videoFrame内将pixelBuffer转为SampleBuffer并交给AVSampleBufferDisplayLayer进行渲染; - 6、使用系统 API开启画中画功能:[self.pipViewController startPictureInPicture]; - */ - /* Picture-in-picture Example (supported by iOS15 and above) MLVB APP picture-in-picture function code example: @@ -94,7 +82,8 @@ - (void)setupPipController { self.pipViewController = [[AVPictureInPictureController alloc] initWithContentSource:contentSource]; self.pipViewController.delegate = self; self.pipViewController.canStartPictureInPictureAutomaticallyFromInline = YES; - self.pipViewController.requiresLinearPlayback = YES; // 设置画中画小窗中是否有快进快退按钮 + self.pipViewController.requiresLinearPlayback = YES; + // Set whether there are fast forward and rewind buttons in the small picture-in-picture window } else { NSLog(@"%@",localize(@"MLVB-API-Example.Home.NotSupported")); } diff --git a/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAnchorViewController.m b/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAnchorViewController.m index 8422d17..92c470b 100644 --- a/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAnchorViewController.m +++ b/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAnchorViewController.m @@ -6,16 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* - RTC连麦+超低延时播放的主播视角 - MLVB RTC连麦+超低延时播放的主播视角 - 本文件展示如何集成RTC连麦+超低延时播放功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、打开摄像头 API: [self.livePusher startCamera:true]; - 3、开始推流 API:[self.livePusher startPush:url]; - 4、拉观众的流 API: [self.livePlayer startLivePlay:url]; - 目前仅中国大陆支持,其他地区正陆续开发中。 - */ /* RTC Co-anchoring + Ultra-low-latency Playback View for Anchors RTC Co-anchoring + Ultra-low-latency Playback View for Anchors in the MLVB App diff --git a/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAudienceViewController.m b/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAudienceViewController.m index 42dd5bc..1f3c849 100644 --- a/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAudienceViewController.m +++ b/MLVB-API-Example-OC/Advanced/RTCPushAndPlay/RTCPushAndPlayAudienceViewController.m @@ -6,17 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* - RTC连麦+超低延时播放的观众视角 - MLVB RTC连麦+超低延时播放的观众视角 - 本文件展示如何集成RTC连麦+超低延时播放功能 - 1、拉主播的流 API: [self.livePlayer startLivePlay:url]; - 2、打开扬声器 API:[self.livePusher startMicrophone]; - 3、打开摄像头 API: [self.livePusher startCamera:true]; - 4、开始推流 API:[self.livePusher startPush:url]; - 目前仅中国大陆支持,其他地区正陆续开发中。 - - */ /* RTC Co-anchoring + Ultra-low-latency Playback View for Audience RTC Co-anchoring + Ultra-low-latency Playback View for Audience in MLVB App diff --git a/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyFaceunityViewController.m b/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyFaceunityViewController.m index ec55e39..12a0b0d 100644 --- a/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyFaceunityViewController.m +++ b/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyFaceunityViewController.m @@ -6,19 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* - 第三方美颜功能示例 - MLVB APP 支持第三方美颜功能 - 本文件展示如何集成第三方美颜功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、打开摄像头 API: [self.livePusher startCamera:true]; - 3、开始推流 API:[self.livePusher startPush:url]; - 4、开启自定义视频处理 API: [self.livePusher enableCustomVideoProcess:true pixelFormat:V2TXLivePixelFormatNV12 bufferType:V2TXLiveBufferTypePixelBuffer]; - 5、使用第三方美颜SDK: API: [[FUManager shareManager] renderItemsToPixelBuffer:srcFrame.pixelBuffer]; - - 参考文档:https://cloud.tencent.com/document/product/647/34066 - 第三方美颜:https://github.com/Faceunity/FUTRTCDemo - */ /* Third-Party Beauty Filter Example The MLVB app supports third-party beauty filters. diff --git a/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyTencentEffectViewController.m b/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyTencentEffectViewController.m index 54bb0e1..871cc9f 100644 --- a/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyTencentEffectViewController.m +++ b/MLVB-API-Example-OC/Advanced/ThirdBeauty/ThirdBeautyTencentEffectViewController.m @@ -7,17 +7,7 @@ // /* - 第三方美颜功能示例 - 接入步骤: - 第一步:集成腾讯特效SDK并拷贝资源(可参考腾讯特效提供的接入文档:https://cloud.tencent.com/document/product/616/65887 ) - 第二步:腾讯特效SDK的鉴权与初始化,详见[self setupBeautySDK],License获取请参考 {https://cloud.tencent.com/document/product/616/65878} - 第三步:在MLVB中使用腾讯特效美颜,详见[self onProcessVideoFrame]中的[self processVideoFrameWithTextureId]方法 - - 开启自定义视频处理 API: [self.livePusher enableCustomVideoProcess:true pixelFormat:V2TXLivePixelFormatNV12 bufferType:V2TXLiveBufferTypePixelBuffer] - - 在 [self.livePusher enableCustomVideoProcess] 回调方法中使用第三方美颜处理视频数据,详见API说明文档 {https://liteav.sdk.qcloud.com/doc/api/zh-cn/group__TRTCCloudListener__android.html#a22afb08b2a1a18563c7be28c904b166a} - - 注意:腾讯特效提供的 License 与 applicationId 一一对应的,测试过程中需要修改 applicationId 为 License对应的applicationId - - + Examples of third-party beauty features Access steps: First step:Integrate Tencent Effect SDK and copy resources(You can refer to the access document provided by Tencent Effects:https://cloud.tencent.com/document/product/616/65888) Second step:Authentication and initialization of Tencent Effect SDK, diff --git a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.h b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.h index c3fd8ef..adb29f2 100755 --- a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.h +++ b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.h @@ -3,7 +3,7 @@ // TXLiteAVSDK // // Created by annidyfeng on 2018/8/10. -// Copyright © 2018年 Tencent. All rights reserved. +// Copyright © 2018 Tencent. All rights reserved. // #import diff --git a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.m b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.m index 5521e7a..6256e64 100755 --- a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.m +++ b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftHelper.m @@ -3,7 +3,7 @@ // TXLiteAVSDK // // Created by annidyfeng on 2018/8/10. -// Copyright © 2018年 Tencent. All rights reserved. +// Copyright © 2018 Tencent. All rights reserved. // #import "TimeShiftHelper.h" diff --git a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftViewController.m b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftViewController.m index f1e7081..87a6905 100644 --- a/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftViewController.m +++ b/MLVB-API-Example-OC/Advanced/TimeShiftPlay/TimeShiftViewController.m @@ -7,28 +7,28 @@ // /* - 时移功能 - MLVB APP 时移代码示例: - 本文件展示如何通过移动直播SDK实现时移功能 - 1、首先在官网了解时移基本概念和使用,并开启时移功能。https://cloud.tencent.com/document/product/267/32742 - 2、根据文档规则拼接时移的播放链接 NSString *timeShiftUrl = http://[Domain]/timeshift/[AppName]/[StreamName]/timeshift.m3u8?delay=90。(delay ,默认最小90秒) - 3、停止当前正在播放的直播流 API:[_livePlayer stopPlay]; - 4、开始播放时移流 API:[self.livePlayer startLivePlay:timeShiftUrl]; - - 恢复直播流 - 1、停止当前正在播放的时移流 API:[_livePlayer stopPlay]; - 2、开始播放直播流 API:[self.livePlayer startLivePlay:liveUrl]; + time shift function + MLVB APP time-shift code example: + This document shows how to implement the time shift function through the mobile live broadcast SDK + 1. First, understand the basic concepts and uses of time shifting on the official website, and enable the time shifting function. https://cloud.tencent.com/document/product/267/32742 + 2. Splice the time-shifted playback link according to the document rules NSString *timeShiftUrl = http://[Domain]/timeshift/[AppName]/[StreamName]/timeshift.m3u8?delay=90. (delay, default minimum 90 seconds) + 3. Stop the currently playing live streaming API: [_livePlayer stopPlay]; + 4. Start playing time-shift streaming API: [self.livePlayer startLivePlay:timeShiftUrl]; + + Resume live stream + 1. Stop the currently playing time-shifted stream API: [_livePlayer stopPlay]; + 2. Start playing live streaming API: [self.livePlayer startLivePlay:liveUrl]; */ #import "TimeShiftViewController.h" #import "TimeShiftHelper.h" -/// 时移功能演示,示例拉流地址。 +/// Time shift function demonstration, sample streaming address。 static NSString * const G_DEFAULT_URL = @"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid.flv"; static NSString * const G_DEFAULT_TIME_SHIFT_DOMAIN = @"liteavapp.timeshift.qcloud.com"; -// 时移区间可配置 https://cloud.tencent.com/document/product/267/32742 +// Configurable time shift interval https://cloud.tencent.com/document/product/267/32742 static const NSInteger kMaxFallbackSeconds = 600; static const NSInteger kMinFallbackSeconds = 90; @@ -50,7 +50,7 @@ - (V2TXLivePlayer *)livePlayer { if (!_livePlayer) { _livePlayer = [[V2TXLivePlayer alloc] init]; [_livePlayer setObserver:self]; - // 停止拉流时是否清理最后一帧 + // Whether to clean the last frame when stopping streaming [_livePlayer setProperty:@"clearLastImage" value:@(NO)]; [_livePlayer setRenderFillMode:V2TXLiveFillModeFit]; [_livePlayer setRenderView:self.view]; @@ -111,7 +111,7 @@ - (NSInteger)getCurrentDelay { return (NSInteger)(delay + 0.5); } -// 返回直播 +// Return to live broadcast - (void)resumeLive { NSLog(@"Resmue live"); self.slider.value = 1.0; diff --git a/MLVB-API-Example-OC/App/Common/URLUtils.m b/MLVB-API-Example-OC/App/Common/URLUtils.m index 325eee3..bf2c740 100644 --- a/MLVB-API-Example-OC/App/Common/URLUtils.m +++ b/MLVB-API-Example-OC/App/Common/URLUtils.m @@ -7,9 +7,9 @@ // /* - * MLVB 移动直播地址生成 + * MLVB mobile live broadcast address generation * - * 详情请参考:「https://cloud.tencent.com/document/product/454/7915」 + * For details, please refer to:「https://cloud.tencent.com/document/product/454/7915」 */ #import "URLUtils.h" diff --git a/MLVB-API-Example-OC/App/Home/ViewController.m b/MLVB-API-Example-OC/App/Home/ViewController.m index 3ee50a9..57bca9a 100755 --- a/MLVB-API-Example-OC/App/Home/ViewController.m +++ b/MLVB-API-Example-OC/App/Home/ViewController.m @@ -90,6 +90,11 @@ - (NSArray *)homeData { @"title": localize(@"MLVB-API-Example.Home.TimeShift"), @"desc": @"", @"class": @"TimeShiftViewController" + }, + @{ + @"title": localize(@"MLVB-API-Example.Home.NewTimeShiftSprite"), + @"desc": @"", + @"class": @"NewTimeShiftSpriteViewController" } ]}]; diff --git a/MLVB-API-Example-OC/Basic/LebPlay/LebPlayViewController.m b/MLVB-API-Example-OC/Basic/LebPlay/LebPlayViewController.m index d6980b8..d058b08 100644 --- a/MLVB-API-Example-OC/Basic/LebPlay/LebPlayViewController.m +++ b/MLVB-API-Example-OC/Basic/LebPlay/LebPlayViewController.m @@ -1,12 +1,4 @@ // Copyright © 2022 Tencent. All rights reserved. -/* - 快直播拉流 - MLVB APP 快直播拉流功能 - 本文件展示如何集成快直播拉流功能 - 1、设置渲染的view API:[self.livePlayer setRenderView:self.view]; - 2、开始播放 API:[self.livePlayer startLivePlay:url]; - 参考文档:https://cloud.tencent.com/document/product/454/55880 - */ /* LEB Playback LEB Playback in MLVB App diff --git a/MLVB-API-Example-OC/Basic/LiveLink/LiveInputBaseViewController.h b/MLVB-API-Example-OC/Basic/LiveLink/LiveInputBaseViewController.h index 344838a..6a10f28 100644 --- a/MLVB-API-Example-OC/Basic/LiveLink/LiveInputBaseViewController.h +++ b/MLVB-API-Example-OC/Basic/LiveLink/LiveInputBaseViewController.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN /** - Link和Pk输入页面基类 + Link and Pk input page base class */ @interface LiveInputBaseViewController : UIViewController diff --git a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAnchorViewController.m b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAnchorViewController.m index 2facb20..9c86971 100644 --- a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAnchorViewController.m +++ b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAnchorViewController.m @@ -6,17 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* -主播连麦 - MLVB APP 主播连麦功能 - 本文件展示如何集成主播连麦功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、开始采集屏幕 API:[self.livePusher startScreenCapture:@"group.com.tencent.liteav.RPLiveStreamShare"]; - 3、开始推流 API:[self.livePusher startPush:url]; - 4、开始拉观众的流 API:[self.livePlayer startLivePlay:url]; - 5、和观众的流进行混流 API:[self.livePusher setMixTranscodingConfig:config]; - 参考文档:https://cloud.tencent.com/document/product/454/52751 - */ /* Anchor-Initiated Co-anchoring Anchor-Initiated Co-anchoring in MLVB App diff --git a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAudienceViewController.m b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAudienceViewController.m index 5f8626e..2e702e7 100644 --- a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAudienceViewController.m +++ b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkAudienceViewController.m @@ -6,19 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* -观众连麦 - MLVB APP 观众连麦功能 - 本文件展示如何集成观众连麦功能 - 1、设置渲染的view API:[self.livePlayer setRenderView:self.view]; - 2、开始快直播拉流 API:[self.livePlayer startLivePlay:url]; - 3、停止快直播拉流 API:[self.livePlayer startLivePlay:url]; - 4、开始推流 API:[self.livePusher startPush:url]; - 5、开始RTC拉流:API:[self.livePlayer startLivePlay:url]; - 参考文档:https://cloud.tencent.com/document/product/454/52751 - 目前仅中国大陆支持,其他地区正陆续开发中。 - - */ /* Audience-Initiated Co-anchoring Audience-Initiated Co-anchoring in MLVB App diff --git a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkUserInputViewController.h b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkUserInputViewController.h index a731982..a903cdc 100644 --- a/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkUserInputViewController.h +++ b/MLVB-API-Example-OC/Basic/LiveLink/LiveLinkUserInputViewController.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN /** - Link用户输入页面 + LinkUser input page */ @interface LiveLinkUserInputViewController : LiveInputBaseViewController diff --git a/MLVB-API-Example-OC/Basic/LivePK/LivePkAnchorViewController.m b/MLVB-API-Example-OC/Basic/LivePK/LivePkAnchorViewController.m index 376066b..c5a428e 100644 --- a/MLVB-API-Example-OC/Basic/LivePK/LivePkAnchorViewController.m +++ b/MLVB-API-Example-OC/Basic/LivePK/LivePkAnchorViewController.m @@ -7,19 +7,6 @@ // /* -主播PK - MLVB APP 主播PK功能 - 本文件展示如何集成主播PK功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、开始采集屏幕 API:[self.livePusher startScreenCapture:@"group.com.tencent.liteav.RPLiveStreamShare"]; - 3、开始推流 API:[self.livePusher startPush:url]; - 4、开始拉主播的流 API:[self.livePlayer startLivePlay:url]; - 5、和主播的流进行混流 API:[self.livePusher setMixTranscodingConfig:config]; - 参考文档:https://cloud.tencent.com/document/product/454/52751 - 目前仅中国大陆支持,其他地区正陆续开发中。 - */ -/* -主播PK Anchor Competition Anchor Competition in MLVB App This document shows how to integrate the anchor competition feature. diff --git a/MLVB-API-Example-OC/Basic/LivePK/LivePkUserInputViewController.h b/MLVB-API-Example-OC/Basic/LivePK/LivePkUserInputViewController.h index a29ab2e..b2c06c9 100644 --- a/MLVB-API-Example-OC/Basic/LivePK/LivePkUserInputViewController.h +++ b/MLVB-API-Example-OC/Basic/LivePK/LivePkUserInputViewController.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN /** - Pk用户输入页面 + Pk user input page */ @interface LivePkUserInputViewController : LiveInputBaseViewController diff --git a/MLVB-API-Example-OC/Basic/LivePlay/LivePlayViewController.m b/MLVB-API-Example-OC/Basic/LivePlay/LivePlayViewController.m index ed8c721..c452267 100644 --- a/MLVB-API-Example-OC/Basic/LivePlay/LivePlayViewController.m +++ b/MLVB-API-Example-OC/Basic/LivePlay/LivePlayViewController.m @@ -6,16 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* - 直播拉流 - MLVB APP 直播拉流功能 - 本文件展示如何集成直播拉流功能 - 1、设置渲染的view API:[self.livePlayer setRenderView:self.view]; - 2、开始播放 API:[self.livePlayer startLivePlay:url]; - 参考文档:https://cloud.tencent.com/document/product/454/56597 - RTC拉流目前仅中国大陆支持,其他地区正陆续开发中。 - - */ /* Playback Playback in MLVB App diff --git a/MLVB-API-Example-OC/Basic/LivePushCamera/LivePushCameraViewController.m b/MLVB-API-Example-OC/Basic/LivePushCamera/LivePushCameraViewController.m index f2bc3a5..50748e3 100644 --- a/MLVB-API-Example-OC/Basic/LivePushCamera/LivePushCameraViewController.m +++ b/MLVB-API-Example-OC/Basic/LivePushCamera/LivePushCameraViewController.m @@ -6,16 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* -摄像头推流 - MLVB APP 摄像头推流功能 - 本文件展示如何集成摄像头推流功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、打开摄像头 API: [self.livePusher startCamera:true]; - 3、开始推流 API:[self.livePusher startPush:url]; - 参考文档:https://cloud.tencent.com/document/product/454/56594 - RTC推流目前仅中国大陆支持,其他地区正陆续开发中。 - */ /* Publishing from Camera Publishing from Camera in MLVB App diff --git a/MLVB-API-Example-OC/Basic/LivePushScreen/LivePushScreenViewController.m b/MLVB-API-Example-OC/Basic/LivePushScreen/LivePushScreenViewController.m index 71806d1..4a3fcad 100644 --- a/MLVB-API-Example-OC/Basic/LivePushScreen/LivePushScreenViewController.m +++ b/MLVB-API-Example-OC/Basic/LivePushScreen/LivePushScreenViewController.m @@ -6,16 +6,6 @@ // Copyright © 2021 Tencent. All rights reserved. // -/* -录屏推流 - MLVB APP 录屏推流功能 - 本文件展示如何集成录屏推流功能 - 1、打开扬声器 API:[self.livePusher startMicrophone]; - 2、开始采集屏幕 API:[self.livePusher startScreenCapture:@"group.com.tencent.liteav.RPLiveStreamShare"]; - 3、开始推流 API:[self.livePusher startPush:url]; - 参考文档:https://cloud.tencent.com/document/product/454/56591 - RTC推流目前仅中国大陆支持,其他地区正陆续开发中。 - */ /* Publishing from Screen Publishing from Screen in MLVB App diff --git a/MLVB-API-Example-OC/Debug/GenerateTestUserSig.h b/MLVB-API-Example-OC/Debug/GenerateTestUserSig.h index 4d70091..a92cdbb 100755 --- a/MLVB-API-Example-OC/Debug/GenerateTestUserSig.h +++ b/MLVB-API-Example-OC/Debug/GenerateTestUserSig.h @@ -1,23 +1,5 @@ // Copyright © 2021 Tencent. All rights reserved. -/* - * Module: GenerateTestUserSig - * - * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。 - * 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。 - * - * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下: - * - * 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品, - * 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。 - * 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。 - * - * 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。 - * 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。 - * - * Reference:https://cloud.tencent.com/document/product/647/17275#Server - */ - /* * Module: GenerateTestUserSig * @@ -27,7 +9,7 @@ * Attention: do not use the code below in your commercial app. This is because: * * The code may be able to calculate UserSig correctly, but it is only for quick testing of the SDK’s basic features, not for commercial apps. - * `SECRETKEY` in client code can be easily decompiled and reversed, especially on web. + * `SDKSECRETKEY` in client code can be easily decompiled and reversed, especially on web. * Once your key is disclosed, attackers will be able to steal your Tencent Cloud traffic. * * The correct method is to deploy the `UserSig` calculation code and encryption key on your project server so that your app can request from your server a `UserSig` that is calculated whenever one is needed. @@ -41,25 +23,25 @@ NS_ASSUME_NONNULL_BEGIN /** - * 配置推流地址 - * 腾讯云域名管理页面:https://console.cloud.tencent.com/live/domainmanage + * Configure push address + * Tencent Cloud domain name management page: https://console.cloud.tencent.com/live/domainmanage */ static NSString * const PUSH_DOMAIN = @""; /** - * 配置拉流地址 - * 腾讯云域名管理页面: https://console.cloud.tencent.com/live/domainmanage + * Configure the streaming address + * Tencent Cloud domain name management page: https://console.cloud.tencent.com/live/domainmanage */ static NSString * const PLAY_DOMAIN = @""; /** - * URL 鉴权Key + * URL authentication key */ static NSString * const LIVE_URL_KEY = @""; /** - * 腾讯云License管理页面(https://console.cloud.tencent.com/live/license) - * 当前应用的License LicenseUrl + * Tencent Cloud License management page (https://console.cloud.tencent.com/live/license) + * Currently applied License LicenseUrl * * License Management View (https://console.cloud.tencent.com/live/license) * License URL of your application @@ -67,20 +49,14 @@ static NSString * const LIVE_URL_KEY = @""; static NSString * const LICENSEURL = @""; /** - * 腾讯云License管理页面(https://console.cloud.tencent.com/live/license) - * 当前应用的License Key + * Tencent Cloud License management page (https://console.cloud.tencent.com/live/license) + * Currently applied License Key * * License Management View (https://console.cloud.tencent.com/live/license) * License key of your application */ static NSString * const LICENSEURLKEY = @""; -/** - * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。 - * - * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId, - * 它是腾讯云用于区分客户的唯一标识。 - */ /** * Tencent Cloud `SDKAppID`. Set it to the `SDKAppID` of your account. * @@ -89,12 +65,6 @@ static NSString * const LICENSEURLKEY = @""; */ static const int SDKAppID = 0; -/** - * 签名过期时间,建议不要设置的过短 - * - * 时间单位:秒 - * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天 - */ /** * Signature validity period, which should not be set too short *

@@ -103,16 +73,7 @@ static const int SDKAppID = 0; */ static const int EXPIRETIME = 0; -/** - * 计算签名用的加密密钥,获取步骤如下: - * - * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个, - * step2. 单击您的应用,并进一步找到“快速上手”部分。 - * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中 - * - * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。 - * 文档:https://cloud.tencent.com/document/product/647/17275#Server - */ + /** * Follow the steps below to obtain the key required for UserSig calculation. * @@ -123,26 +84,11 @@ static const int EXPIRETIME = 0; * Note: this method is for testing only. Before commercial launch, please migrate the UserSig calculation code and key to your backend server to prevent key disclosure and traffic stealing. * Reference: https://cloud.tencent.com/document/product/647/17275#Server */ -static NSString * const SECRETKEY = @""; +static NSString * const SDKSECRETKEY = @""; @interface GenerateTestUserSig : NSObject -/** - * 计算 UserSig 签名 - * - * 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。 - * - * @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下: - * - * 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品, - * 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。 - * 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。 - * - * 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。 - * 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。 - * - * 文档:https://cloud.tencent.com/document/product/647/17275#Server - */ + /** * Calculating UserSig * @@ -151,7 +97,7 @@ static NSString * const SECRETKEY = @""; * @note: do not use the code below in your commercial app. This is because: * * The code may be able to calculate UserSig correctly, but it is only for quick testing of the SDK’s basic features, not for commercial apps. - * `SECRETKEY` in client code can be easily decompiled and reversed, especially on web. + * `SDKSECRETKEY` in client code can be easily decompiled and reversed, especially on web. * Once your key is disclosed, attackers will be able to steal your Tencent Cloud traffic. * * The correct method is to deploy the `UserSig` calculation code on your project server so that your app can request from your server a `UserSig` that is calculated whenever one is needed. diff --git a/MLVB-API-Example-OC/Debug/GenerateTestUserSig.m b/MLVB-API-Example-OC/Debug/GenerateTestUserSig.m index 52ebc38..8f76c9d 100755 --- a/MLVB-API-Example-OC/Debug/GenerateTestUserSig.m +++ b/MLVB-API-Example-OC/Debug/GenerateTestUserSig.m @@ -52,7 +52,7 @@ + (NSString *)genTestUserSig:(NSString *)identifier + (NSString *)hmac:(NSString *)plainText { - const char *cKey = [SECRETKEY cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cKey = [SDKSECRETKEY cStringUsingEncoding:NSUTF8StringEncoding]; const char *cData = [plainText cStringUsingEncoding:NSUTF8StringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; diff --git a/MLVB-API-Example-OC/MLVB-API-Example-OC.xcodeproj/project.pbxproj b/MLVB-API-Example-OC/MLVB-API-Example-OC.xcodeproj/project.pbxproj index 223c3b8..149f4e3 100644 --- a/MLVB-API-Example-OC/MLVB-API-Example-OC.xcodeproj/project.pbxproj +++ b/MLVB-API-Example-OC/MLVB-API-Example-OC.xcodeproj/project.pbxproj @@ -113,7 +113,10 @@ EB147B18282B908100C0E2DC /* ThirdBeautyTencentEffectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EB147B17282B908100C0E2DC /* ThirdBeautyTencentEffectViewController.xib */; }; EB147B1B282D2F1200C0E2DC /* ThirdBeautyEntranceViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EB147B1A282D2F1200C0E2DC /* ThirdBeautyEntranceViewController.xib */; }; EB147B1D282D2F1700C0E2DC /* ThirdBeautyEntranceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EB147B1C282D2F1700C0E2DC /* ThirdBeautyEntranceViewController.m */; }; - ED14F7FE2B957E6500E52959 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED14F7FD2B957E6500E52959 /* CoreMotion.framework */; }; + ED10B3822BD6081600B28019 /* NewTimeShiftSpriteViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = ED10B37F2BD6081600B28019 /* NewTimeShiftSpriteViewController.xib */; }; + ED10B3832BD6081600B28019 /* NewTimeShiftSpriteViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED10B3812BD6081600B28019 /* NewTimeShiftSpriteViewController.m */; }; + ED10B3852BD614DF00B28019 /* TXSpriteImageFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = ED10B3842BD614DF00B28019 /* TXSpriteImageFetcher.m */; }; + ED14F7F22B91D5C100E52959 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED14F7F12B91D5C100E52959 /* CoreMotion.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -301,7 +304,12 @@ EB147B19282D2F0D00C0E2DC /* ThirdBeautyEntranceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThirdBeautyEntranceViewController.h; sourceTree = ""; }; EB147B1A282D2F1200C0E2DC /* ThirdBeautyEntranceViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ThirdBeautyEntranceViewController.xib; sourceTree = ""; }; EB147B1C282D2F1700C0E2DC /* ThirdBeautyEntranceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThirdBeautyEntranceViewController.m; sourceTree = ""; }; - ED14F7FD2B957E6500E52959 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; + ED10B37F2BD6081600B28019 /* NewTimeShiftSpriteViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NewTimeShiftSpriteViewController.xib; sourceTree = ""; }; + ED10B3802BD6081600B28019 /* NewTimeShiftSpriteViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewTimeShiftSpriteViewController.h; sourceTree = ""; }; + ED10B3812BD6081600B28019 /* NewTimeShiftSpriteViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewTimeShiftSpriteViewController.m; sourceTree = ""; }; + ED10B3842BD614DF00B28019 /* TXSpriteImageFetcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TXSpriteImageFetcher.m; sourceTree = ""; }; + ED10B3862BD614ED00B28019 /* TXSpriteImageFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TXSpriteImageFetcher.h; sourceTree = ""; }; + ED14F7F12B91D5C100E52959 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; FB3939E2552F6AFE9F587046 /* Pods-MLVB-API-Example-OC.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MLVB-API-Example-OC.debug.xcconfig"; path = "Target Support Files/Pods-MLVB-API-Example-OC/Pods-MLVB-API-Example-OC.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -310,7 +318,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - ED14F7FE2B957E6500E52959 /* CoreMotion.framework in Frameworks */, + ED14F7F22B91D5C100E52959 /* CoreMotion.framework in Frameworks */, 4723A7C426315FAA0094AC81 /* AVFoundation.framework in Frameworks */, 406AB164280048BB00A99B81 /* VideoToolbox.framework in Frameworks */, 88167CEC2685BF97001D99DC /* libz.tbd in Frameworks */, @@ -450,6 +458,7 @@ 47E0727A2636A6C80027D05E /* Advanced */ = { isa = PBXGroup; children = ( + ED10B37E2BD6081600B28019 /* NewTimeShiftSprite */, 8873801928D9E49100B0479E /* LebAutoBitrate */, 8873802A28E18C8B00B0479E /* HlsAutoBitrate */, 47F149E0286BF3A600781688 /* PictureInPicture */, @@ -679,7 +688,7 @@ 88ED6FE02624364700C75B9D /* Frameworks */ = { isa = PBXGroup; children = ( - ED14F7FD2B957E6500E52959 /* CoreMotion.framework */, + ED14F7F12B91D5C100E52959 /* CoreMotion.framework */, 88BC38A12844710E00814931 /* GLKit.framework */, 47748037283E21F900505C4C /* CoreServices.framework */, 406AB169280048E100A99B81 /* MetalKit.framework */, @@ -732,6 +741,18 @@ path = Pods; sourceTree = ""; }; + ED10B37E2BD6081600B28019 /* NewTimeShiftSprite */ = { + isa = PBXGroup; + children = ( + ED10B37F2BD6081600B28019 /* NewTimeShiftSpriteViewController.xib */, + ED10B3802BD6081600B28019 /* NewTimeShiftSpriteViewController.h */, + ED10B3812BD6081600B28019 /* NewTimeShiftSpriteViewController.m */, + ED10B3842BD614DF00B28019 /* TXSpriteImageFetcher.m */, + ED10B3862BD614ED00B28019 /* TXSpriteImageFetcher.h */, + ); + path = NewTimeShiftSprite; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -834,6 +855,7 @@ 8839C3CB2689B93F000FF58C /* LivePlayEnterViewController.xib in Resources */, 477EC9A826268D0F007AAC4F /* Localized.strings in Resources */, 88167CB4268488C2001D99DC /* LivePushCameraEnterViewController.xib in Resources */, + ED10B3822BD6081600B28019 /* NewTimeShiftSpriteViewController.xib in Resources */, 88C4C063268B503000FBB698 /* CustomVideoCaptureViewController.xib in Resources */, C1937C9C274F799200F19E99 /* LiveLinkAudienceViewController.xib in Resources */, 88A1A885268DA7DA007F630D /* LivePkAnchorViewController.xib in Resources */, @@ -936,6 +958,7 @@ C1937C94274F799200F19E99 /* LiveLinkOrPkSwitchRoleViewController.m in Sources */, C1937C64274F75F700F19E99 /* LivePkUserInputViewController.m in Sources */, 88A1A88A268DA81A007F630D /* LivePkAudienceViewController.m in Sources */, + ED10B3852BD614DF00B28019 /* TXSpriteImageFetcher.m in Sources */, 477EC9C32626D6AB007AAC4F /* UIColor+Hex.m in Sources */, C1937C9B274F799200F19E99 /* LiveLinkAnchorViewController.m in Sources */, C1937C9A274F799200F19E99 /* LiveInputBaseViewController.m in Sources */, @@ -953,6 +976,7 @@ 885A56472689ABB500D9D55F /* LivePushScreenEnterViewController.m in Sources */, C1937C99274F799200F19E99 /* LiveLinkUserInputViewController.m in Sources */, 477ECA0A2627D344007AAC4F /* UIViewController+AlertViewController.m in Sources */, + ED10B3832BD6081600B28019 /* NewTimeShiftSpriteViewController.m in Sources */, 47F149E4286BF3E900781688 /* PictureInPictureViewController.m in Sources */, 8839C3D52689BEF5000FF58C /* LivePlayViewController.m in Sources */, C1937CBD275080CB00F19E99 /* LivePkFindPkUserController.m in Sources */, diff --git a/MLVB-API-Example-OC/README.cn.md b/MLVB-API-Example-OC/README-zh_CN.md similarity index 91% rename from MLVB-API-Example-OC/README.cn.md rename to MLVB-API-Example-OC/README-zh_CN.md index d071f14..edc61f7 100644 --- a/MLVB-API-Example-OC/README.cn.md +++ b/MLVB-API-Example-OC/README-zh_CN.md @@ -34,7 +34,7 @@ ### 前提条件 您已 [注册腾讯云](https://cloud.tencent.com/document/product/378/17985) 账号,并完成 [实名认证](https://cloud.tencent.com/document/product/378/3629)。 -### 申请SDKAPPID 和 SECRETKEY +### 申请SDKAPPID 和 SDKSECRETKEY 1. 登录实时音视频控制台,选择【开发辅助】>【[快速跑通Demo](https://console.cloud.tencent.com/trtc/quickstart)】。 2. 单击【立即开始】,输入您的应用名称,例如`TestTRTC`,单击【创建应用】。 @@ -51,14 +51,14 @@ 3. 配置`GenerateTestUserSig.h`文件中的参数: - SDKAPPID:替换该变量值为上一步骤中在页面上看到的 SDKAppID。 - - SECRETKEY:替换该变量值为上一步骤中在页面上看到的密钥。 + - SDKSECRETKEY:替换该变量值为上一步骤中在页面上看到的密钥。 - LICENSEURL:默认为 PLACEHOLDER ,请设置为实际的License Url信息; - LICENSEURLKEY:默认为 PLACEHOLDER ,请设置为实际的License Key信息; - PUSH_DOMAIN 中推流地址请设置为您的推流域名的 `CNAME`。 - PLAY_DOMAIN 中拉流地址请设置为您的播放域名的 `CNAME`。 - LIVE_URL_KEY:非必需,用于生成 txSecret 等鉴权信息。 ->!本文提到的生成 UserSig 的方案是在客户端代码中配置 SECRETKEY,该方法中 SECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。 +>!本文提到的生成 UserSig 的方案是在客户端代码中配置 SDKSECRETKEY,该方法中 SDKSECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试**。 >正确的 UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向 App 的接口,在需要 UserSig 时由您的 App 向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275#Server)。 ### 编译运行 diff --git a/MLVB-API-Example-OC/README.md b/MLVB-API-Example-OC/README.md index 9391ac2..e2eaf9d 100644 --- a/MLVB-API-Example-OC/README.md +++ b/MLVB-API-Example-OC/README.md @@ -1,5 +1,5 @@ # MLVB API-Example -[简体中文](README.cn.md) | English +[简体中文](README-zh_CN.md) | English ## Background This open-source demo shows how to use some APIs of the [MLVB SDK](https://www.tencentcloud.com/document/product/1071) to help you better understand the APIs and use them to implement some basic MLVB features. @@ -50,14 +50,14 @@ You have [signed up for a Tencent Cloud account](https://intl.cloud.tencent.com/ 3. Set parameters in `GenerateTestUserSig.h` as follows: - `SDKAPPID`: set it to the `SDKAppID` obtained in the previous step. - - `SECRETKEY`: set it to the secret key obtained in the previous step. + - `SDKSECRETKEY`: set it to the secret key obtained in the previous step. - `LICENSEURL`: a placeholder by default. Set it to the actual license URL. - `LICENSEURLKEY`: a placeholder by default. Set it to the actual license key. - `PUSH_DOMAIN`: set it to the configured publishing URL. - `PLAY_DOMAIN`: set it to the configured playback URL. - `LIVE_URL_KEY`: set it to the authentication key (if authentication configuration is enabled). ->!The method for generating `UserSig` described in this document involves configuring `SECRETKEY` in client code. In this method, `SECRETKEY` may be easily decompiled and reversed, and if your key is disclosed, attackers can steal your Tencent Cloud traffic. Therefore, **this method is suitable only for the local execution and debugging of the demo**. +>!The method for generating `UserSig` described in this document involves configuring `SDKSECRETKEY` in client code. In this method, `SDKSECRETKEY` may be easily decompiled and reversed, and if your key is disclosed, attackers can steal your Tencent Cloud traffic. Therefore, **this method is suitable only for the local execution and debugging of the demo**. >The correct `UserSig` distribution method is to integrate the calculation code of `UserSig` into your server and provide an application-oriented API. When `UserSig` is needed, your application can send a request to the business server for a dynamic `UserSig`. For more information, please see [How do I calculate UserSig on the server?](https://www.tencentcloud.com/document/product/1071/39471). ## Compiling and running the project diff --git a/MLVB-API-Example-OC/Resource/Localized/en.lproj/Localized.strings b/MLVB-API-Example-OC/Resource/Localized/en.lproj/Localized.strings index efe0e75..38e9dc9 100644 --- a/MLVB-API-Example-OC/Resource/Localized/en.lproj/Localized.strings +++ b/MLVB-API-Example-OC/Resource/Localized/en.lproj/Localized.strings @@ -38,6 +38,7 @@ "MLVB-API-Example.Home.TimeShift.ResumeLive" = "Resume Live"; +"MLVB-API-Example.Home.NewTimeShiftSprite" = "New Time Shift Sprite"; "MLVB-API-Example.LivePushCamera.title" = "MLVB Publishing (Camera)"; "MLVB-API-Example.LivePushCamera.streamIdInput" = "Stream ID"; "MLVB-API-Example.LivePushCamera.audioQualityInput" = "Audio Quality"; diff --git a/MLVB-API-Example-OC/Resource/Localized/zh-Hans.lproj/Localized.strings b/MLVB-API-Example-OC/Resource/Localized/zh-Hans.lproj/Localized.strings index f815962..766e311 100644 --- a/MLVB-API-Example-OC/Resource/Localized/zh-Hans.lproj/Localized.strings +++ b/MLVB-API-Example-OC/Resource/Localized/zh-Hans.lproj/Localized.strings @@ -40,6 +40,7 @@ "MLVB-API-Example.Home.TimeShift.ResumeLive" = "返回直播"; +"MLVB-API-Example.Home.NewTimeShiftSprite" = "新直播时移雪碧图"; "MLVB-API-Example.LivePushCamera.title" = "MLVB 摄像头推流"; "MLVB-API-Example.LivePushCamera.streamIdInput" = "请输入streamId"; "MLVB-API-Example.LivePushCamera.audioQualityInput" = "请选择音频质量";