VapxMP4Decoder.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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",@"3.0",
  60. @"-b:v", self.bitRate?: @"2000k",
  61. @"-bf", @"0",
  62. /*@"-crf", @"29",*/
  63. @"-bufsize", @"2000k", output] mutableCopy];
  64. if (isVp9) {
  65. arguments = [@[@"-framerate", [NSString stringWithFormat:@"%@", @(MAX(self.fps, 1))],
  66. @"-pattern_type", @"glob",
  67. @"-i", inputPath,
  68. @"-c:v", @"libvpx-vp9",
  69. @"-pix_fmt", self.yuvFormat?:@"yuv420p",
  70. @"-b:v", self.bitRate?: @"2000k", output] mutableCopy];
  71. }
  72. if (self.audioPath.length > 0) {
  73. if (isVp9) {
  74. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"libopus",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  75. } else {
  76. [arguments insertObjects:@[@"-i",self.audioPath,@"-c:a",@"aac",@"-ab", @"112k"] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(6, 6)]];
  77. }
  78. }
  79. NSPipe *pipe = [NSPipe pipe];
  80. NSFileHandle * read = [pipe fileHandleForReading];
  81. NSTask *task = [[NSTask alloc] init];
  82. [task setLaunchPath: ffmpegPath];
  83. [task setArguments: arguments];
  84. [task setStandardOutput: pipe];
  85. [task launch];
  86. [task waitUntilExit];
  87. NSData* data = [read readDataToEndOfFile];
  88. NSString* stringOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  89. NSLog(@"stringOutput:%@, terminationStatus:%i",stringOutput, [task terminationStatus]);
  90. return output;
  91. }
  92. @end