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

发布于 2024-10-04 01:47:29 字数 713 浏览 2 评论 0原文

我会制作缩小尺寸的视频,宽度可能为 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

I would make reduced size video, maybe 50 pixel across and 75 pixels for length. Those are the physical dimension.

How do you set that? in the videosettings? I think AVVideoWidthKey and AVVideoHeightKey are more for resolution not for physically dimension which what I needed.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野心澎湃 2024-10-11 01:47:29

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

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];

You need to set video codec parameters:

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];
贪了杯 2024-10-11 01:47:29

您需要拥有博士学位才​​能使用 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);
    }
  }];
}

You need a PhD to work with AVAssetWriter - it's non-trivial:
https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/05_Export.html#//apple_ref/doc/uid/TP40010188-CH9-SW1

There's an amazing library for doing exactly what you want which is just an AVAssetExportSession drop-in replacement with more crucial features like changing the bit rate: https://github.com/rs/SDAVAssetExportSession

Here's how to use it:

-(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);
    }
  }];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文