ViewController.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // Tencent is pleased to support the open source community by making vap available.
  2. //
  3. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the MIT License (the "License"); you may not use this file except in
  6. // compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://opensource.org/licenses/MIT
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed under the License is
  11. // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  12. // either express or implied. See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import "ViewController.h"
  15. #import "VapxProcessor.h"
  16. #import "VapMergeInfoView.h"
  17. #import "VapProgressHUD.h"
  18. @interface ViewController () <VapMergeInfoViewDelegate>
  19. @property (nonatomic, strong) VapxFileHelper *fileHelper;
  20. @property (nonatomic, strong) NSMutableArray<VapMergeInfoView *> *mergeInfoViews;
  21. @property (weak) IBOutlet NSTextField *basicInfoLabel;
  22. @property (strong) IBOutlet NSView *uploadFramesButton;
  23. @property (weak) IBOutlet NSTextField *uploadFramesTipsLabel;
  24. @property (weak) IBOutlet NSButton *generateButton;
  25. @property (weak) IBOutlet NSTextField *versionLabel;
  26. @property (weak) IBOutlet NSTextField *fpsLabel;
  27. @property (weak) IBOutlet NSTextField *bitRateLabel;
  28. @property (weak) IBOutlet NSTextField *alphaScaleLabel;
  29. @property (weak) IBOutlet NSButton *addMergeInfoButton;
  30. @property (weak) IBOutlet NSTextField *mergeInfoLabel;
  31. @property (weak) IBOutlet NSView *mergeInfoArea;
  32. @property (weak) IBOutlet NSTextField *addMergeInfoLabel;
  33. @property (weak) IBOutlet NSButton *uploadAudioButton;
  34. @property (nonatomic, assign) BOOL hasUploadedVideoFrames;
  35. @property (nonatomic, strong) NSString *audioPath;
  36. @property (nonatomic, assign) BOOL classicMode;
  37. @property (nonatomic, assign) NSEdgeInsets layoutPadding;
  38. @end
  39. @implementation ViewController
  40. - (IBAction)onClassicModeButtonClicked:(NSButton *)sender {
  41. if (sender.state == NSControlStateValueOn) {
  42. self.classicMode = YES;
  43. } else {
  44. self.classicMode = NO;
  45. }
  46. [self refreshUIForClassicMode];
  47. }
  48. - (void)refreshUIForClassicMode {
  49. if (self.classicMode) {
  50. self.alphaScaleLabel.stringValue = @"1.0";
  51. self.addMergeInfoButton.enabled = NO;
  52. [self.mergeInfoViews enumerateObjectsUsingBlock:^(VapMergeInfoView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  53. [obj removeFromSuperview];
  54. }];
  55. [self.mergeInfoViews removeAllObjects];
  56. [self rearrangeMergeInfoArea];
  57. self.layoutPadding = NSEdgeInsetsZero;
  58. self.alphaScaleLabel.enabled = NO;
  59. } else {
  60. self.addMergeInfoButton.enabled = YES;
  61. self.layoutPadding = NSEdgeInsetsMake(4, 4, 4, 4);
  62. self.alphaScaleLabel.enabled = YES;
  63. }
  64. }
  65. - (IBAction)onOpenOuputFolderBtnClicked:(id)sender {
  66. NSString *output = _fileHelper.outputPath;
  67. NSURL *folderURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@",output]];
  68. [[NSWorkspace sharedWorkspace] openURL:folderURL];
  69. }
  70. - (IBAction)onGenerateButtonClick:(id)sender {
  71. NSString *errorString = [self checkInputingValid];
  72. if (errorString) {
  73. NSAlert *alert = [[NSAlert alloc] init];
  74. [alert setMessageText:@"生成vap文件失败"];
  75. [alert setInformativeText:errorString];
  76. [alert addButtonWithTitle:@"Ok"];
  77. [alert runModal];
  78. return ;
  79. }
  80. VapxProcessor *processor = [VapxProcessor new];
  81. processor.fileHelper = _fileHelper;
  82. processor.version = [_versionLabel.stringValue integerValue];
  83. processor.fps = [_fpsLabel.stringValue integerValue];
  84. processor.bitrates = [_bitRateLabel.stringValue integerValue];
  85. processor.alphaScale = [_alphaScaleLabel.stringValue floatValue];
  86. processor.mergeInfoViews = _mergeInfoViews;
  87. processor.audioPath = self.audioPath;
  88. processor.layoutPadding = self.layoutPadding;
  89. processor.classicMode = self.classicMode;
  90. VapProgressHUD *hud = [VapProgressHUD showHUDToSuperView:self.view];
  91. [processor process:^(CGFloat progress) {
  92. dispatch_async(dispatch_get_main_queue(), ^{
  93. hud.currentValue = progress*100;
  94. });
  95. } onCompletion:^(BOOL success, NSString *output, NSError *error) {
  96. hud.currentValue = 100;
  97. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  98. [hud hide];
  99. });
  100. if (!success || error) {
  101. NSAlert *alert = [[NSAlert alloc] init];
  102. [alert setMessageText:@"生成vap文件失败"];
  103. error = error ?: [NSError errorWithDomain:@"未知错误" code:-1 userInfo:nil];
  104. [alert setInformativeText:error.localizedDescription];
  105. [alert addButtonWithTitle:@"Ok"];
  106. [alert runModal];
  107. } else {
  108. NSAlert *alert = [[NSAlert alloc] init];
  109. [alert setMessageText:@"生成vap文件成功!"];
  110. [alert setInformativeText:output];
  111. [alert addButtonWithTitle:@"Ok"];
  112. [alert runModal];
  113. NSURL *folderURL = [[NSURL URLWithString:[NSString stringWithFormat:@"file://%@",output]] URLByDeletingLastPathComponent];
  114. [[NSWorkspace sharedWorkspace] openURL:folderURL];
  115. }
  116. }];
  117. }
  118. - (IBAction)addMergeInfoAreaDidClicked:(id)sender {
  119. VapMergeInfoView *mergInfoView = [[VapMergeInfoView alloc] initWithFrame:NSMakeRect(0, 0, 900, 60)];
  120. mergInfoView.delegate = self;
  121. mergInfoView.fileHelper = _fileHelper;
  122. [_mergeInfoViews addObject:mergInfoView];
  123. [self rearrangeMergeInfoArea];
  124. [self.mergeInfoArea addSubview:mergInfoView];
  125. }
  126. - (void)rearrangeMergeInfoArea {
  127. CGFloat singleHeight = 70;
  128. CGFloat height = _mergeInfoViews.count*singleHeight;
  129. self.mergeInfoArea.frame = NSMakeRect(CGRectGetMinX(self.mergeInfoArea.frame), CGRectGetMaxY(self.mergeInfoLabel.frame)-height, CGRectGetWidth(self.mergeInfoArea.frame), height);
  130. __weak __typeof(_mergeInfoViews) weakInfoViews = _mergeInfoViews;
  131. [_mergeInfoViews enumerateObjectsUsingBlock:^(VapMergeInfoView * _Nonnull mergeView, NSUInteger idx, BOOL * _Nonnull stop) {
  132. [mergeView setIndex:idx+1];
  133. mergeView.frame = NSMakeRect(0, (weakInfoViews.count-1-idx)*singleHeight, 900, singleHeight);
  134. }];
  135. self.addMergeInfoButton.frame = NSMakeRect(CGRectGetMinX(self.addMergeInfoButton.frame), CGRectGetMinY(self.mergeInfoArea.frame)-CGRectGetHeight(self.addMergeInfoButton.frame), CGRectGetWidth(self.addMergeInfoButton.frame), CGRectGetHeight(self.addMergeInfoButton.frame));
  136. self.addMergeInfoLabel.frame = NSMakeRect(CGRectGetMinX(self.addMergeInfoLabel.frame), CGRectGetMinY(self.mergeInfoArea.frame)-CGRectGetHeight(self.addMergeInfoButton.frame)/2.0-CGRectGetHeight(self.addMergeInfoLabel.frame)/2.0, CGRectGetWidth(self.addMergeInfoLabel.frame), CGRectGetHeight(self.addMergeInfoLabel.frame));
  137. }
  138. - (IBAction)uploadAudioButtonDidClick:(id)sender {
  139. NSOpenPanel *openPanel = [NSOpenPanel new];
  140. openPanel.allowsMultipleSelection = YES;
  141. openPanel.canChooseDirectories = NO;
  142. openPanel.canChooseFiles = YES;
  143. NSModalResponse res = [openPanel runModal];
  144. if (res == NSModalResponseOK) {
  145. NSString *audioPath = [self.fileHelper saveUploadedAudioFile:openPanel.URL];
  146. self.audioPath = audioPath;
  147. self.uploadAudioButton.title = @"上传成功";
  148. } else {
  149. self.audioPath = nil;
  150. self.uploadAudioButton.title = @"error, retry";
  151. }
  152. }
  153. - (IBAction)uploadFramesButtonDidClick:(id)sender {
  154. NSOpenPanel *openPanel = [NSOpenPanel new];
  155. openPanel.allowsMultipleSelection = YES;
  156. openPanel.canChooseDirectories = NO;
  157. openPanel.canChooseFiles = YES;
  158. NSModalResponse res = [openPanel runModal];
  159. if (res == NSModalResponseOK) {
  160. [self.fileHelper saveUploadedVideoFrames:openPanel.URLs];
  161. self.uploadFramesTipsLabel.stringValue = [NSString stringWithFormat:@"成功上传%@个文件",@(openPanel.URLs.count)];
  162. [self.uploadFramesTipsLabel sizeToFit];
  163. self.uploadFramesTipsLabel.hidden = NO;
  164. self.hasUploadedVideoFrames = YES;
  165. } else {
  166. self.hasUploadedVideoFrames = NO;
  167. }
  168. }
  169. - (IBAction)openSourceInfoButtonDidClicked:(id)sender {
  170. NSString *documentsPath = [[NSBundle mainBundle] pathForResource:@"Draft_License_VAP_HK20200804" ofType:@"txt"];
  171. NSString *content = [NSString stringWithContentsOfFile:documentsPath encoding:NSUTF8StringEncoding error:nil];
  172. CGFloat width = 600;
  173. CGFloat height = 400;
  174. NSTextView *accessory = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,width,height)];
  175. NSFont *font =[NSFont systemFontOfSize:[NSFont systemFontSize]];
  176. NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
  177. [accessory insertText:[[NSAttributedString alloc] initWithString:content attributes:textAttributes] replacementRange:NSMakeRange(0, content.length)];
  178. [accessory setEditable:NO];
  179. [accessory setDrawsBackground:NO];
  180. [accessory setSelectable:NO];
  181. NSScrollView*scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
  182. [scrollView setDocumentView:accessory];
  183. [scrollView setHasVerticalScroller:YES];
  184. [scrollView setHasHorizontalScroller:YES];
  185. [scrollView setBorderType:NSNoBorder];
  186. NSWindow *mFileInfoWindow= [[NSWindow alloc] initWithContentRect:NSMakeRect(800, 600, width, height) styleMask:NSWindowStyleMaskTitled |NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO];
  187. NSView *contentView = [mFileInfoWindow contentView];
  188. [contentView addSubview:scrollView];
  189. //[[NSApplication sharedApplication] runModalForWindow:mFileInfoWindow];
  190. NSWindowController *vc = [[NSWindowController alloc] initWithWindow:mFileInfoWindow];
  191. [vc showWindow:nil];
  192. }
  193. - (void)viewDidLoad {
  194. [super viewDidLoad];
  195. // Do any additional setup after loading the view.
  196. _mergeInfoViews = [NSMutableArray new];
  197. self.fileHelper = [VapxFileHelper new];
  198. [self.fileHelper clearCurrentWorkSpace];
  199. [self.fileHelper createCurrentWorkSpaceIfNeed];
  200. self.uploadFramesTipsLabel.hidden = YES;
  201. [self setupUIComponents];
  202. self.layoutPadding = NSEdgeInsetsMake(4, 4, 4, 4);
  203. }
  204. - (void)setupUIComponents {
  205. self.generateButton.layer.zPosition = 1000;
  206. [self.generateButton.cell setBackgroundColor:[NSColor colorWithRed:299/255.0 green:133/255.0 blue:61/255.0 alpha:1]];
  207. }
  208. - (void)setRepresentedObject:(id)representedObject {
  209. [super setRepresentedObject:representedObject];
  210. // Update the view, if already loaded.
  211. }
  212. - (void)didClickAtCloseButton:(VapMergeInfoView *)view {
  213. [view removeFromSuperview];
  214. [_mergeInfoViews removeObject:view];
  215. [self rearrangeMergeInfoArea];
  216. }
  217. - (NSString *)checkInputingValid {
  218. if (_versionLabel.stringValue.length == 0) {
  219. return @"版本号不能为空!";
  220. }
  221. if (_fpsLabel.stringValue.length == 0) {
  222. return @"fps不能为空!";
  223. }
  224. if (_bitRateLabel.stringValue.length == 0) {
  225. return @"码率不能为空!";
  226. }
  227. if (_alphaScaleLabel.stringValue.length == 0) {
  228. return @"alphaScale不能为空!";
  229. }
  230. if (!self.hasUploadedVideoFrames) {
  231. return @"请上传视频帧!";
  232. }
  233. for (int i = 0; i < self.mergeInfoViews.count; i++) {
  234. VapMergeInfoView *mergeInfoView = self.mergeInfoViews[i];
  235. if (mergeInfoView.tagLabel.stringValue.length == 0) {
  236. return [@"占位符不能为空!" stringByAppendingString:[NSString stringWithFormat:@"-第%@个遮罩",@(i+1)]];
  237. }
  238. if (mergeInfoView.widthLabel.stringValue.length == 0) {
  239. return [@"宽度不能为空!" stringByAppendingString:[NSString stringWithFormat:@"-第%@个遮罩",@(i+1)]];
  240. }
  241. if (mergeInfoView.tagLabel.stringValue.length == 0) {
  242. return [@"高度不能为空!" stringByAppendingString:[NSString stringWithFormat:@"-第%@个遮罩",@(i+1)]];
  243. }
  244. if (mergeInfoView.maskPath.length == 0) {
  245. return [@"请上传遮罩文件!" stringByAppendingString:[NSString stringWithFormat:@"-第%@个遮罩",@(i+1)]];
  246. }
  247. if ([mergeInfoView.resTypePopButton.selectedItem.title isEqualToString:@"文字"]) {
  248. if (mergeInfoView.colorLabel.stringValue.length == 0) {
  249. return [@"文字颜色不能为空!" stringByAppendingString:[NSString stringWithFormat:@"-第%@个遮罩",@(i+1)]];
  250. }
  251. }
  252. }
  253. return nil;
  254. }
  255. @end