如何使用AVAssetWriter制作缩小尺寸的视频?

10

我会制作缩小尺寸的视频,可能宽50像素,长度75像素。这些是物理尺寸。

如何设置呢?在视频设置中吗?我认为AVVideoWidthKey和AVVideoHeightKey更多用于分辨率而不是我需要的物理尺寸。

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt: 320], AVVideoWidthKey,    
                               [NSNumber numberWithInt:480], AVVideoHeightKey,   
                               nil];
AVAssetWriterInput* writerInput = [[AVAssetWriterInput
                                    assetWriterInputWithMediaType:AVMediaTypeVideo
                                    outputSettings:videoSettings] retain
2个回答

20

你需要设置视频编解码器参数:

NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                           [NSNumber numberWithInt:320], AVVideoCleanApertureWidthKey,
                                           [NSNumber numberWithInt:480], AVVideoCleanApertureHeightKey,
                                           [NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey,
                                           [NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey,
                                            nil];


NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [NSNumber numberWithInt:3], AVVideoPixelAspectRatioHorizontalSpacingKey,
                                             [NSNumber numberWithInt:3],AVVideoPixelAspectRatioVerticalSpacingKey,
                                                    nil];



NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               [NSNumber numberWithInt:960000], AVVideoAverageBitRateKey,
                               [NSNumber numberWithInt:1],AVVideoMaxKeyFrameIntervalKey,
                               videoCleanApertureSettings, AVVideoCleanApertureKey,
                               //videoAspectRatioSettings, AVVideoPixelAspectRatioKey,
                               //AVVideoProfileLevelH264Main30, AVVideoProfileLevelKey,
                               nil];





NSString *targetDevice = [[UIDevice currentDevice] model];

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               codecSettings,AVVideoCompressionPropertiesKey,
                               [NSNumber numberWithInt:320], AVVideoWidthKey,
                               [NSNumber numberWithInt:480], AVVideoHeightKey,
                               nil];

为什么要使用 [NSNumber numberWithInt:1],AVVideoMaxKeyFrameIntervalKey? - Meekohi
1
@Meekohi:AVVideoMaxKeyFrameIntervalKey 指定了访问关键帧之间最大间隔的关键。相应的值是 NSNumber 的一个实例。1 表示仅关键帧。 - Regexident
3
抱歉,我理解它的技术含义,但我的问题是为什么在这种情况下你会有意这样做?这不会降低压缩最终视频的能力吗? - Meekohi
我尝试使用320x320,但现在我的视频被挤在一起了。 - MichaelScaria

9
您需要拥有博士学位才能使用 AVAssetWriter 进行工作 - 非常复杂: https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/05_Export.html#//apple_ref/doc/uid/TP40010188-CH9-SW1 有一个非常棒的库可以实现您想要的功能,它只是一个 AVAssetExportSession 的替代品,并具有更重要的功能,如改变比特率:https://github.com/rs/SDAVAssetExportSession 这是如何使用它:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{

  SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:[AVAsset assetWithURL:[info objectForKey:UIImagePickerControllerMediaURL]]];
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDirectory = [paths objectAtIndex:0];
  self.myPathDocs =  [documentsDirectory stringByAppendingPathComponent:
                      [NSString stringWithFormat:@"lowerBitRate-%d.mov",arc4random() % 1000]];
  NSURL *url = [NSURL fileURLWithPath:self.myPathDocs];
  encoder.outputURL=url;
  encoder.outputFileType = AVFileTypeMPEG4;
  encoder.shouldOptimizeForNetworkUse = YES;

  encoder.videoSettings = @
  {
  AVVideoCodecKey: AVVideoCodecH264,
  AVVideoCompressionPropertiesKey: @
    {
    AVVideoAverageBitRateKey: @2300000,
    AVVideoProfileLevelKey: AVVideoProfileLevelH264High40,
    },
  };
  encoder.audioSettings = @
  {
  AVFormatIDKey: @(kAudioFormatMPEG4AAC),
  AVNumberOfChannelsKey: @2,
  AVSampleRateKey: @44100,
  AVEncoderBitRateKey: @128000,
  };

  [encoder exportAsynchronouslyWithCompletionHandler:^
  {
    int status = encoder.status;

    if (status == AVAssetExportSessionStatusCompleted)
    {
      AVAssetTrack *videoTrack = nil;
      AVURLAsset *asset = [AVAsset assetWithURL:encoder.outputURL];
      NSArray *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
      videoTrack = [videoTracks objectAtIndex:0];
      float frameRate = [videoTrack nominalFrameRate];
      float bps = [videoTrack estimatedDataRate];
      NSLog(@"Frame rate == %f",frameRate);
      NSLog(@"bps rate == %f",bps/(1024.0 * 1024.0));
      NSLog(@"Video export succeeded");
      // encoder.outputURL <- this is what you want!!
    }
    else if (status == AVAssetExportSessionStatusCancelled)
    {
      NSLog(@"Video export cancelled");
    }
    else
    {
      NSLog(@"Video export failed with error: %@ (%d)", encoder.error.localizedDescription, encoder.error.code);
    }
  }];
}

请问我需要在这个库中设置哪些参数才能使用AVVideoProfileLevelH264Baseline30?我尝试了将您的设置替换为AVVideoProfileLevelH264High40,但是报错了,所以我猜测这些设置不适用于基线3.0。提前感谢@etayluz。 - Gannicus
@etayluz,AVVideoAverageBitRateKey可以使用哪些值范围?此外,根据给定的AVVideoAverageBitRateKey值,其他属性应如何更改? - ThE uSeFuL
我希望我能告诉你,但是我已经将其搁置了将近4年。 - etayluz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接