VapxMP4Decoder.m 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 "VapxMP4Decoder.h"
  15. #import "AppDelegate.h"
  16. @implementation VapxMP4Decoder
  17. + (NSString *)encodeWithDir:(NSString *)directory outputName:(NSString *)output fps:(NSInteger)fps bitRate:(NSString *)bitRate audioPath:(NSString *)audioPath {
  18. VapxMP4Decoder *encoder = [VapxMP4Decoder new];
  19. encoder.resourceDirectory = directory;
  20. encoder.outputName = output;
  21. encoder.fps = fps;
  22. encoder.bitRate = bitRate;
  23. encoder.audioPath = audioPath;
  24. return [encoder encode];
  25. }
  26. - (NSString *)encode {
  27. NSFileManager *fileManager = [NSFileManager defaultManager];
  28. if (self.resourceDirectory.length == 0 || ![fileManager fileExistsAtPath:self.resourceDirectory]) {
  29. return nil;
  30. }
  31. if (!self.outputName) {
  32. return nil;
  33. }
  34. NSString *ffmpegPath = [[NSBundle mainBundle] pathForResource:@"ffmpeg" ofType:@""];
  35. NSString *inputPath = [self.resourceDirectory stringByAppendingPathComponent:@"*.png"];
  36. __block NSString *outputName = self.outputName;
  37. __block BOOL isVp9;
  38. dispatch_sync(dispatch_get_main_queue(), ^{
  39. isVp9 = [[(AppDelegate *)[NSApplication sharedApplication].delegate encoder] isEqualToString:@"libvpx-vp9"];
  40. if (isVp9) {
  41. outputName = [outputName stringByReplacingOccurrencesOfString:@"mp4" withString:@"webm"];
  42. }
  43. });
  44. __block BOOL isH265;
  45. dispatch_sync(dispatch_get_main_queue(), ^{
  46. isH265 = [[(AppDelegate *)[NSApplication sharedApplication].delegate encoder] isEqualToString:@"libx265"];
  47. });
  48. NSString *output = [self.resourceDirectory stringByAppendingPathComponent:outputName];
  49. if ([fileManager fileExistsAtPath:output]) {
  50. NSError *error = nil;
  51. [[NSFileManager defaultManager] removeItemAtPath:output error:&error];
  52. if (error) {
  53. NSLog(@"removeItemAtPath:%@ fail!", output);
  54. return nil;
  55. }
  56. }
  57. NSMutableArray *arguments = nil;
  58. if (isH265) {
  59. arguments = [@[@"-r", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  60. @"-pattern_type", @"glob",
  61. @"-i", inputPath,
  62. @"-c:v", @"libx265",
  63. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  64. @"-profile:v", self.profile?:@"main",
  65. @"-level",@"4.0",
  66. @"-b:v", self.bitRate?: @"2000k",
  67. /*@"-bf", @"0",*/
  68. @"-crf", @"29",
  69. @"-tag:v", @"hvc1", output] mutableCopy];
  70. } else if (isVp9) {
  71. arguments = [@[@"-framerate", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  72. @"-pattern_type", @"glob",
  73. @"-i", inputPath,
  74. @"-c:v", @"libvpx-vp9",
  75. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  76. @"-b:v", self.bitRate?: @"2000k", output] mutableCopy];
  77. } else {
  78. arguments = [@[@"-r", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  79. @"-pattern_type", @"glob",
  80. @"-i", inputPath,
  81. @"-c:v", @"libx264",
  82. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  83. @"-profile:v", self.profile?:@"high",
  84. @"-level",@"4.0",
  85. @"-b:v", self.bitRate?: @"2000k",
  86. @"-bf", @"0",
  87. /*@"-crf", @"29",*/
  88. @"-bufsize", @"2000k", output] mutableCopy];
  89. }
  90. if (self.audioPath.length > 0) {
  91. if (isVp9) {
  92. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"libopus",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  93. } else {
  94. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"aac",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  95. }
  96. }
  97. NSPipe *pipe = [NSPipe pipe];
  98. NSFileHandle * read = [pipe fileHandleForReading];
  99. NSTask *task = [[NSTask alloc] init];
  100. [task setLaunchPath: ffmpegPath];
  101. [task setArguments: arguments];
  102. [task setStandardOutput: pipe];
  103. [task launch];
  104. [task waitUntilExit];
  105. NSData* data = [read readDataToEndOfFile];
  106. NSString* stringOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  107. NSLog(@"stringOutput:%@, terminationStatus:%i",stringOutput, [task terminationStatus]);
  108. return output;
  109. }
  110. @end