VapxMP4Decoder.m 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. NSString *output = [self.resourceDirectory stringByAppendingPathComponent:outputName];
  45. if ([fileManager fileExistsAtPath:output]) {
  46. NSError *error = nil;
  47. [[NSFileManager defaultManager] removeItemAtPath:output error:&error];
  48. if (error) {
  49. NSLog(@"removeItemAtPath:%@ fail!", output);
  50. return nil;
  51. }
  52. }
  53. NSMutableArray *arguments = [@[@"-r", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  54. @"-pattern_type", @"glob",
  55. @"-i", inputPath,
  56. @"-c:v", @"libx264",
  57. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  58. @"-profile:v", self.profile?:@"high",
  59. @"-level",@"4.0",
  60. @"-b:v", self.bitRate?: @"2000k",
  61. @"-bf", @"0",
  62. /*@"-crf", @"29",*/
  63. @"-bufsize", @"2000k", output] mutableCopy];
  64. arguments = [@[@"-r", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  65. @"-pattern_type", @"glob",
  66. @"-i", inputPath,
  67. @"-c:v", @"libx265",
  68. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  69. @"-profile:v", self.profile?:@"main",
  70. @"-level",@"4.0",
  71. @"-b:v", self.bitRate?: @"2000k",
  72. /*@"-bf", @"0",*/
  73. @"-crf", @"29",
  74. /*@"-tag:v", @"hvc1",*/ output] mutableCopy];
  75. if (isVp9) {
  76. arguments = [@[@"-framerate", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  77. @"-pattern_type", @"glob",
  78. @"-i", inputPath,
  79. @"-c:v", @"libvpx-vp9",
  80. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  81. @"-b:v", self.bitRate?: @"2000k", output] mutableCopy];
  82. }
  83. if (self.audioPath.length > 0) {
  84. if (isVp9) {
  85. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"libopus",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  86. } else {
  87. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"aac",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  88. }
  89. }
  90. NSPipe *pipe = [NSPipe pipe];
  91. NSFileHandle * read = [pipe fileHandleForReading];
  92. NSTask *task = [[NSTask alloc] init];
  93. [task setLaunchPath: ffmpegPath];
  94. [task setArguments: arguments];
  95. [task setStandardOutput: pipe];
  96. [task launch];
  97. [task waitUntilExit];
  98. NSData* data = [read readDataToEndOfFile];
  99. NSString* stringOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  100. NSLog(@"stringOutput:%@, terminationStatus:%i",stringOutput, [task terminationStatus]);
  101. return output;
  102. }
  103. @end