TUICaptureVideoPreviewViewController.m 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Created by Tencent on 2023/06/09.
  2. // Copyright © 2023 Tencent. All rights reserved.
  3. #import "TUICaptureVideoPreviewViewController.h"
  4. #import <TIMCommon/TIMCommonModel.h>
  5. #import <TIMCommon/TIMDefine.h>
  6. @import AVFoundation;
  7. @interface TUICaptureVideoPreviewViewController ()
  8. @property(nonatomic) NSURL *fileURL;
  9. @property(nonatomic) AVPlayer *player;
  10. @property(nonatomic) AVPlayerItem *item;
  11. @property(nonatomic) AVPlayerLayer *playerLayer;
  12. @property(nonatomic) UIButton *commitButton;
  13. @property(nonatomic) UIButton *cancelButton;
  14. @property(nonatomic) CGRect lastRect;
  15. @property(nonatomic) BOOL onShow;
  16. @property(nonatomic) BOOL onReadyToPlay;
  17. @end
  18. @implementation TUICaptureVideoPreviewViewController
  19. - (instancetype)initWithVideoURL:(NSURL *)url {
  20. self = [super initWithNibName:nil bundle:nil];
  21. if (self) {
  22. _fileURL = url;
  23. }
  24. return self;
  25. }
  26. - (void)viewDidLoad {
  27. [super viewDidLoad];
  28. // Do any additional setup after loading the view.
  29. self.view.backgroundColor = [UIColor blackColor];
  30. self.item = [[AVPlayerItem alloc] initWithURL:self.fileURL];
  31. self.player = [[AVPlayer alloc] initWithPlayerItem:self.item];
  32. self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  33. [self.view.layer addSublayer:self.playerLayer];
  34. self.commitButton = [UIButton buttonWithType:UIButtonTypeCustom];
  35. UIImage *commitImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"camer_commit")];
  36. [self.commitButton setImage:commitImage forState:UIControlStateNormal];
  37. UIImage *commitBGImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"camer_commitBg")];
  38. [self.commitButton setBackgroundImage:commitBGImage forState:UIControlStateNormal];
  39. [self.commitButton addTarget:self action:@selector(commitButtonClick:) forControlEvents:UIControlEventTouchUpInside];
  40. [self.view addSubview:self.commitButton];
  41. self.cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
  42. UIImage *cancelButtonBGImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"camera_cancel")];
  43. [self.cancelButton setBackgroundImage:[cancelButtonBGImage rtl_imageFlippedForRightToLeftLayoutDirection] forState:UIControlStateNormal];
  44. [self.cancelButton addTarget:self action:@selector(cancelButtonClick:) forControlEvents:UIControlEventTouchUpInside];
  45. [self.view addSubview:self.cancelButton];
  46. [self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
  47. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.item];
  48. }
  49. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context {
  50. if ([keyPath isEqualToString:@"status"]) {
  51. AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
  52. if (status == AVPlayerStatusReadyToPlay) {
  53. self.onReadyToPlay = YES;
  54. [self playVideo];
  55. }
  56. }
  57. }
  58. - (void)playVideo {
  59. [TUITool dispatchMainAsync:^{
  60. if (self.onShow && self.onReadyToPlay) {
  61. [self.player play];
  62. }
  63. }];
  64. }
  65. - (void)viewDidAppear:(BOOL)animated {
  66. [super viewDidAppear:animated];
  67. self.onShow = YES;
  68. [self playVideo];
  69. }
  70. - (void)viewWillLayoutSubviews {
  71. [super viewWillLayoutSubviews];
  72. if (!CGRectEqualToRect(self.lastRect, self.view.bounds)) {
  73. self.lastRect = self.view.bounds;
  74. self.playerLayer.frame = self.view.bounds;
  75. CGFloat commitButtonWidth = 80.0;
  76. CGFloat buttonDistance = (self.view.bounds.size.width - 2 * commitButtonWidth) / 3.0;
  77. CGFloat commitButtonY = self.view.bounds.size.height - commitButtonWidth - 50.0;
  78. CGFloat commitButtonX = 2 * buttonDistance + commitButtonWidth;
  79. self.commitButton.frame = CGRectMake(commitButtonX, commitButtonY, commitButtonWidth, commitButtonWidth);
  80. CGFloat cancelButtonX = commitButtonWidth;
  81. self.cancelButton.frame = CGRectMake(cancelButtonX, commitButtonY, commitButtonWidth, commitButtonWidth);
  82. if (isRTL()) {
  83. [self.commitButton resetFrameToFitRTL];
  84. [self.cancelButton resetFrameToFitRTL];
  85. }
  86. }
  87. }
  88. - (void)commitButtonClick:(UIButton *)btn {
  89. if (self.commitBlock) {
  90. [self removeObserver];
  91. self.commitBlock();
  92. }
  93. }
  94. - (void)cancelButtonClick:(UIButton *)btn {
  95. if (self.cancelBlock) {
  96. [self removeObserver];
  97. self.cancelBlock();
  98. }
  99. }
  100. - (void)playFinished:(NSNotification *)noti {
  101. [self.player seekToTime:CMTimeMake(0, 1)];
  102. [self.player play];
  103. }
  104. - (void)removeObserver {
  105. [self.item removeObserver:self forKeyPath:@"status"];
  106. [[NSNotificationCenter defaultCenter] removeObserver:self];
  107. }
  108. @end