UGCKitVideoRangeSlider.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // Copyright (c) 2019 Tencent. All rights reserved.
  2. #import "UGCKitVideoRangeSlider.h"
  3. #import "UGCKit_UIViewAdditions.h"
  4. #import "UGCKitVideoRangeConst.h"
  5. @implementation UGCKitVideoColorInfo
  6. @end
  7. @interface UGCKitVideoRangeSlider()<RangeContentDelegate, UIScrollViewDelegate>
  8. @property BOOL disableSeek;
  9. @end
  10. @implementation UGCKitVideoRangeSlider
  11. {
  12. NSMutableArray <UGCKitVideoColorInfo *> *_colorInfos;
  13. UGCKitRangeColorType _colorType;
  14. UGCKitVideoColorInfo *_selectColorInfo;
  15. BOOL _startColor;
  16. }
  17. /*
  18. // Only override drawRect: if you perform custom drawing.
  19. // An empty implementation adversely affects performance during animation.
  20. - (void)drawRect:(CGRect)rect {
  21. // Drawing code
  22. }
  23. */
  24. - (instancetype)initWithFrame:(CGRect)frame
  25. {
  26. self = [super initWithFrame:frame];
  27. self.bgScrollView = ({
  28. UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectZero];
  29. [self addSubview:scroll];
  30. scroll.showsVerticalScrollIndicator = NO;
  31. scroll.showsHorizontalScrollIndicator = NO;
  32. scroll.scrollsToTop = NO;
  33. scroll.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  34. scroll.delegate = self;
  35. scroll;
  36. });
  37. self.middleLine = ({
  38. UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mline.png"]];
  39. [self addSubview:imageView];
  40. imageView;
  41. });
  42. _colorInfos = [NSMutableArray array];
  43. return self;
  44. }
  45. - (void)layoutSubviews {
  46. [super layoutSubviews];
  47. self.bgScrollView.ugckit_width = self.ugckit_width;
  48. self.middleLine.center = self.bgScrollView.center = CGPointMake(self.ugckit_width/2, self.ugckit_height/2);
  49. self.middleLine.bounds = CGRectMake(0, 0, 0, self.ugckit_height + 4);
  50. }
  51. - (void)setAppearanceConfig:(UGCKitRangeContentConfig *)appearanceConfig
  52. {
  53. _appearanceConfig = appearanceConfig;
  54. self.middleLine.image = appearanceConfig.indicatorImage;
  55. }
  56. - (void)setImageList:(NSArray *)images
  57. {
  58. if (self.rangeContent) {
  59. [self.rangeContent removeFromSuperview];
  60. }
  61. if (_appearanceConfig) {
  62. self.rangeContent = [[UGCKitRangeContent alloc] initWithImageList:images config:_appearanceConfig];
  63. } else {
  64. self.rangeContent = [[UGCKitRangeContent alloc] initWithImageList:images];
  65. }
  66. self.rangeContent.delegate = self;
  67. [self.bgScrollView addSubview:self.rangeContent];
  68. self.bgScrollView.contentSize = [self.rangeContent intrinsicContentSize];
  69. self.bgScrollView.ugckit_height = self.bgScrollView.contentSize.height;
  70. self.bgScrollView.contentInset = UIEdgeInsetsMake(0, self.ugckit_width/2-self.rangeContent.pinWidth,
  71. 0, self.ugckit_width/2-self.rangeContent.pinWidth);
  72. [self setCurrentPos:0];
  73. }
  74. - (void)updateImage:(UIImage *)image atIndex:(NSUInteger)index;
  75. {
  76. self.rangeContent.imageViewList[index].image = image;
  77. }
  78. - (void)setLeftPanHidden:(BOOL)isHidden
  79. {
  80. self.rangeContent.leftPin.hidden = isHidden;
  81. [self.rangeContent unpdateBorder];
  82. }
  83. - (void)setCenterPanHidden:(BOOL)isHidden
  84. {
  85. self.rangeContent.centerPin.hidden = isHidden;
  86. }
  87. - (void)setRightPanHidden:(BOOL)isHidden
  88. {
  89. self.rangeContent.rightPin.hidden = isHidden;
  90. [self.rangeContent unpdateBorder];
  91. }
  92. - (void)setLeftPanFrame:(CGFloat)time
  93. {
  94. _leftPos = time;
  95. self.rangeContent.leftPinCenterX = time / _durationMs * self.rangeContent.imageListWidth + self.rangeContent.pinWidth / 2;
  96. self.rangeContent.leftPin.center = CGPointMake(self.rangeContent.leftPinCenterX, self.rangeContent.leftPin.center.y);
  97. [self.rangeContent unpdateBorder];
  98. }
  99. - (void)setCenterPanFrame:(CGFloat)time
  100. {
  101. self.rangeContent.centerPinCenterX = time / _durationMs * self.rangeContent.imageListWidth + self.rangeContent.pinWidth;
  102. self.rangeContent.centerPin.center = CGPointMake(self.rangeContent.centerPinCenterX, self.rangeContent.centerPin.center.y);
  103. }
  104. - (void)setRightPanFrame:(CGFloat)time
  105. {
  106. _rightPos = time;
  107. self.rangeContent.rightPinCenterX = time / _durationMs * self.rangeContent.imageListWidth + self.rangeContent.pinWidth * 3 / 2;
  108. self.rangeContent.rightPin.center = CGPointMake(self.rangeContent.rightPinCenterX, self.rangeContent.rightPin.center.y);
  109. [self.rangeContent unpdateBorder];
  110. }
  111. - (void)setColorType:(UGCKitRangeColorType)UGCKitRangeColorType
  112. {
  113. _colorType = UGCKitRangeColorType;
  114. if (_colorType == UGCKitRangeColorType_Cut) {
  115. [self setLeftPanHidden:NO];
  116. [self setRightPanHidden:NO];
  117. }else{
  118. [self setLeftPanHidden:YES];
  119. [self setRightPanHidden:YES];
  120. [self setLeftPanFrame:0];
  121. [self setRightPanFrame:_rightPos];
  122. [self.rangeContent unpdateBorder];
  123. self.rangeContent.leftCover.hidden = YES;
  124. self.rangeContent.rightCover.hidden = YES;
  125. }
  126. for (UGCKitVideoColorInfo *info in _colorInfos) {
  127. if (info.UGCKitRangeColorType != _colorType) {
  128. info.colorView.hidden = YES;
  129. }else{
  130. info.colorView.hidden = NO;
  131. }
  132. }
  133. }
  134. - (void)startColoration:(UIColor *)color alpha:(CGFloat)alpha
  135. {
  136. UGCKitVideoColorInfo *info = [[UGCKitVideoColorInfo alloc] init];
  137. info.colorView = [UIView new];
  138. info.colorView.backgroundColor = color;
  139. info.colorView.alpha = alpha;
  140. info.UGCKitRangeColorType = _colorType;
  141. [_colorInfos addObject:info];
  142. if (_colorType == UGCKitRangeColorType_Effect) {
  143. info.startPos = _currentPos;
  144. }else{
  145. info.startPos = _leftPos;
  146. info.endPos = _rightPos;
  147. CGFloat x = self.rangeContent.pinWidth + _leftPos * self.rangeContent.imageListWidth / _durationMs;
  148. CGFloat width = fabs(_leftPos - _rightPos) * self.rangeContent.imageListWidth / _durationMs;
  149. info.colorView.frame = CGRectMake(x, 0, width, self.ugckit_height);
  150. }
  151. UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
  152. [info.colorView addGestureRecognizer:tapGes];
  153. [self.rangeContent insertSubview:info.colorView belowSubview:self.rangeContent.leftPin];
  154. _startColor = YES;
  155. _selectColorInfo = info;
  156. }
  157. - (void)stopColoration
  158. {
  159. if (_colorType == UGCKitRangeColorType_Effect) {
  160. UGCKitVideoColorInfo *info = [_colorInfos lastObject];
  161. info.endPos = _currentPos;
  162. if (_currentPos + 1.5/ _fps >= _durationMs) {
  163. info.colorView.frame = [self coloredFrameForStartTime:info.startPos endTime:_durationMs];
  164. info.endPos = _durationMs;
  165. } else {
  166. info.endPos = _currentPos;
  167. }
  168. }
  169. _startColor = NO;
  170. }
  171. - (UGCKitVideoColorInfo *)removeLastColoration:(UGCKitRangeColorType)UGCKitRangeColorType;
  172. {
  173. for (NSInteger i = _colorInfos.count - 1; i >= 0; i --) {
  174. UGCKitVideoColorInfo *info = (UGCKitVideoColorInfo *)_colorInfos[i];
  175. if (info.UGCKitRangeColorType == UGCKitRangeColorType) {
  176. [info.colorView removeFromSuperview];
  177. [_colorInfos removeObject:info];
  178. return info;
  179. }
  180. }
  181. return nil;
  182. }
  183. - (void)removeColoration:(UGCKitRangeColorType)UGCKitRangeColorType index:(NSInteger)index;
  184. {
  185. NSInteger count = 0;
  186. for (NSInteger i = 0; i < _colorInfos.count; i ++) {
  187. UGCKitVideoColorInfo *info = (UGCKitVideoColorInfo *)_colorInfos[i];
  188. if (info.UGCKitRangeColorType == UGCKitRangeColorType) {
  189. if (count == index) {
  190. [info.colorView removeFromSuperview];
  191. [_colorInfos removeObject:info];
  192. break;
  193. }
  194. count++;
  195. }
  196. }
  197. }
  198. - (CGRect)coloredFrameForStartTime:(float)start endTime:(float)end {
  199. CGFloat boxWidth = self.rangeContent.imageListWidth / _durationMs; // 帧的宽度
  200. return CGRectMake(self.rangeContent.pinWidth + start * boxWidth, 0, (end - start) * boxWidth, self.rangeContent.ugckit_height);
  201. }
  202. - (void)setDurationMs:(CGFloat)durationMs {
  203. //duration 发生变化的时候,更新下特效所在的位置
  204. if (_durationMs != durationMs) {
  205. for (UGCKitVideoColorInfo *info in _colorInfos) {
  206. CGFloat x = self.rangeContent.pinWidth + info.startPos * self.rangeContent.imageListWidth / durationMs;
  207. CGFloat width = fabs(info.endPos - info.startPos) * self.rangeContent.imageListWidth / durationMs;
  208. info.colorView.frame = CGRectMake(x, 0, width, self.ugckit_height);
  209. }
  210. _durationMs = durationMs;
  211. }
  212. _leftPos = 0;
  213. _rightPos = _durationMs;
  214. [self setCurrentPos:_currentPos];
  215. _leftPos = self.durationMs * self.rangeContent.leftScale;
  216. _centerPos = self.durationMs * self.rangeContent.centerScale;
  217. _rightPos = self.durationMs * self.rangeContent.rightScale;
  218. }
  219. - (void)setCurrentPos:(CGFloat)currentPos
  220. {
  221. _currentPos = currentPos;
  222. if (_durationMs <= 0) {
  223. return;
  224. }
  225. CGFloat off = currentPos * self.rangeContent.imageListWidth / _durationMs;
  226. // off += self.rangeContent.leftPin.width;
  227. off -= self.bgScrollView.contentInset.left;
  228. self.disableSeek = YES;
  229. self.bgScrollView.contentOffset = CGPointMake(off, 0);
  230. UGCKitVideoColorInfo *info = [_colorInfos lastObject];
  231. if (_colorType == UGCKitRangeColorType_Effect && _startColor) {
  232. CGRect frame;
  233. if (_currentPos > info.startPos) {
  234. frame = [self coloredFrameForStartTime:info.startPos endTime:_currentPos];
  235. }else{
  236. frame = [self coloredFrameForStartTime:_currentPos endTime:info.startPos];
  237. }
  238. info.colorView.frame = frame;
  239. }
  240. self.disableSeek = NO;
  241. }
  242. - (void)handleTap:(UITapGestureRecognizer *)gesture
  243. {
  244. if (gesture.state == UIGestureRecognizerStateEnded) {
  245. CGPoint point = [gesture locationInView:self.rangeContent];
  246. CGFloat tapTime = (point.x - self.rangeContent.pinWidth) / self.rangeContent.imageListWidth * _durationMs;
  247. for (UGCKitVideoColorInfo *info in _colorInfos) {
  248. if (info.UGCKitRangeColorType == _colorType && tapTime >= info.startPos && tapTime <= info.endPos) {
  249. _selectColorInfo = info;
  250. break;
  251. }
  252. }
  253. [self.delegate onVideoRangeTap:tapTime];
  254. }
  255. }
  256. #pragma mark TXVideoRangeContentDelegate
  257. - (void)onRangeLeftChanged:(UGCKitRangeContent *)sender
  258. {
  259. _leftPos = self.durationMs * sender.leftScale;
  260. _rightPos = self.durationMs * sender.rightScale;
  261. [self.delegate onVideoRangeLeftChanged:self];
  262. if (_colorType == UGCKitRangeColorType_Paster || _colorType == UGCKitRangeColorType_Text) {
  263. CGFloat x = self.rangeContent.pinWidth + _leftPos * self.rangeContent.imageListWidth / _durationMs;
  264. CGFloat width = fabs(_leftPos - _rightPos) * self.rangeContent.imageListWidth / _durationMs;
  265. _selectColorInfo.startPos = _leftPos;
  266. _selectColorInfo.colorView.frame = CGRectMake(x, 0, width, self.ugckit_height);
  267. }
  268. }
  269. - (void)onRangeLeftChangeEnded:(UGCKitRangeContent *)sender
  270. {
  271. _leftPos = self.durationMs * sender.leftScale;
  272. _rightPos = self.durationMs * sender.rightScale;
  273. [self.delegate onVideoRangeLeftChangeEnded:self];
  274. }
  275. - (void)onRangeCenterChanged:(UGCKitRangeContent *)sender
  276. {
  277. _leftPos = self.durationMs * sender.leftScale;
  278. _rightPos = self.durationMs * sender.rightScale;
  279. _centerPos = self.durationMs * sender.centerScale;
  280. [self.delegate onVideoRangeCenterChanged:self];
  281. }
  282. - (void)onRangeCenterChangeEnded:(UGCKitRangeContent *)sender
  283. {
  284. _leftPos = self.durationMs * sender.leftScale;
  285. _rightPos = self.durationMs * sender.rightScale;
  286. _centerPos = self.durationMs * sender.centerScale;
  287. [self.delegate onVideoRangeCenterChangeEnded:self];
  288. }
  289. - (void)onRangeRightChanged:(UGCKitRangeContent *)sender
  290. {
  291. _leftPos = self.durationMs * sender.leftScale;
  292. _rightPos = self.durationMs * sender.rightScale;
  293. [self.delegate onVideoRangeRightChanged:self];
  294. if (_colorType == UGCKitRangeColorType_Paster || _colorType == UGCKitRangeColorType_Text) {
  295. CGFloat x = self.rangeContent.pinWidth + _leftPos * self.rangeContent.imageListWidth / _durationMs;
  296. CGFloat width = fabs(_leftPos - _rightPos) * self.rangeContent.imageListWidth / _durationMs;
  297. _selectColorInfo.endPos = _rightPos;
  298. _selectColorInfo.colorView.frame = CGRectMake(x, 0, width, self.ugckit_height);
  299. }
  300. }
  301. - (void)onRangeRightChangeEnded:(UGCKitRangeContent *)sender
  302. {
  303. _leftPos = self.durationMs * sender.leftScale;
  304. _rightPos = self.durationMs * sender.rightScale;
  305. [self.delegate onVideoRangeRightChangeEnded:self];
  306. }
  307. - (void)onRangeLeftAndRightChanged:(UGCKitRangeContent *)sender
  308. {
  309. _leftPos = self.durationMs * sender.leftScale;
  310. _rightPos = self.durationMs * sender.rightScale;
  311. }
  312. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  313. {
  314. CGFloat pos = scrollView.contentOffset.x;
  315. pos += scrollView.contentInset.left;
  316. if (pos < 0) pos = 0;
  317. if (pos > self.rangeContent.imageListWidth) pos = self.rangeContent.imageListWidth;
  318. _currentPos = self.durationMs * pos/self.rangeContent.imageListWidth;
  319. if (self.disableSeek == NO) {
  320. NSLog(@"seek %f", _currentPos);
  321. [self.delegate onVideoRange:self seekToPos:self.currentPos];
  322. }
  323. }
  324. @end