使用 AVFoundation 更改视频帧大小

发布于 2024-11-30 00:26:45 字数 2526 浏览 2 评论 0原文

我正在尝试将视频帧大小更改为方形,即 100 x 100。这是代码:

- (void) changeSize :(NSURL *) url
{

//Create audio/video Settings
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt: 100], AVVideoWidthKey, 
                               [NSNumber numberWithInt:100], AVVideoHeightKey, 
                               nil];

NSDictionary * audioSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
                               [NSNumber numberWithFloat: 44100.0], AVSampleRateKey, 
                               [NSNumber numberWithInt: 2], AVNumberOfChannelsKey, 
                               [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey, 
                               [NSData data], AVChannelLayoutKey, nil];



//Read Asset 
AVURLAsset *myAsset = [AVURLAsset URLAssetWithURL:url options:nil];

NSArray *videoTracks = [myAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *audioTrack = [[myAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];


AVAssetReader *assetReader = [[AVAssetReader alloc]initWithAsset:myAsset error:nil];

AVAssetReaderOutput *videoOutput = [AVAssetReaderVideoCompositionOutput assetReaderVideoCompositionOutputWithVideoTracks:videoTracks videoSettings:nil];

AVAssetReaderOutput *audioOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil];

[assetReader addOutput:videoOutput];
[assetReader addOutput:audioOutput];


//Create writer and set its properties
AVAssetWriterInput* writerInputVideo = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                                                                           outputSettings:videoSettings] retain];

AVAssetWriterInput* writerInputAudio = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
                                                                           outputSettings:nil] retain];


NSError *error = nil;
AVAssetWriter *writer = [[AVAssetWriter alloc]initWithURL:[NSURL fileURLWithPath:fullPath] fileType:AVFileTypeQuickTimeMovie error:&error];

[writer addInput:writerInputVideo];
[writer addInput:writerInputAudio];


//start reading/writting
[writer startWriting];
[assetReader startReading];

}

现在的问题是,当它到达 [assetReader startReading] 时,它会抛出异常,提示“AVssetReaderVideoCompositionOutput.videoComposition 需要设置”。

有人请指导我吗?

TIA

I am trying to change the video frame size to square i.e 100 x 100. Here is the code:

- (void) changeSize :(NSURL *) url
{

//Create audio/video Settings
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt: 100], AVVideoWidthKey, 
                               [NSNumber numberWithInt:100], AVVideoHeightKey, 
                               nil];

NSDictionary * audioSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
                               [NSNumber numberWithFloat: 44100.0], AVSampleRateKey, 
                               [NSNumber numberWithInt: 2], AVNumberOfChannelsKey, 
                               [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey, 
                               [NSData data], AVChannelLayoutKey, nil];



//Read Asset 
AVURLAsset *myAsset = [AVURLAsset URLAssetWithURL:url options:nil];

NSArray *videoTracks = [myAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *audioTrack = [[myAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];


AVAssetReader *assetReader = [[AVAssetReader alloc]initWithAsset:myAsset error:nil];

AVAssetReaderOutput *videoOutput = [AVAssetReaderVideoCompositionOutput assetReaderVideoCompositionOutputWithVideoTracks:videoTracks videoSettings:nil];

AVAssetReaderOutput *audioOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil];

[assetReader addOutput:videoOutput];
[assetReader addOutput:audioOutput];


//Create writer and set its properties
AVAssetWriterInput* writerInputVideo = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                                                                           outputSettings:videoSettings] retain];

AVAssetWriterInput* writerInputAudio = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
                                                                           outputSettings:nil] retain];


NSError *error = nil;
AVAssetWriter *writer = [[AVAssetWriter alloc]initWithURL:[NSURL fileURLWithPath:fullPath] fileType:AVFileTypeQuickTimeMovie error:&error];

[writer addInput:writerInputVideo];
[writer addInput:writerInputAudio];


//start reading/writting
[writer startWriting];
[assetReader startReading];

}

Now the problem is that when it reaches [assetReader startReading], it throws and exception saying "AVAssetReaderVideoCompositionOutput.videoComposition needs to be set".

Anybody please guide me?

TIA

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

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

发布评论

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

评论(1

月亮邮递员 2024-12-07 00:26:45

我自己做的。一探究竟:

- (void) resizeVideo:(NSURL *)videoPath outputPath:(NSURL *)outputPath
{

NSURL *fullPath = outputPath;

NSURL *path = videoPath;


NSLog(@"Write Started");

NSError *error = nil;

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:fullPath fileType:AVFileTypeQuickTimeMovie error:&error];    
NSParameterAssert(videoWriter);

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt:100], AVVideoWidthKey,
                               [NSNumber numberWithInt:100], AVVideoHeightKey,
                               nil];

AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput
                                         assetWriterInputWithMediaType:AVMediaTypeVideo
                                         outputSettings:videoSettings] retain];

NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);

videoWriterInput.expectsMediaDataInRealTime = NO;

[videoWriter addInput:videoWriterInput];




AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:path options:nil];
NSError *aerror = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset error:&aerror];


AVAssetTrack *videoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0];

NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:videoOptions];    

[reader addOutput:asset_reader_output];


[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
[reader startReading];

CMSampleBufferRef buffer;


while ( [reader status]==AVAssetReaderStatusReading )
{
    if(![videoWriterInput isReadyForMoreMediaData])
        continue;

    buffer = [asset_reader_output copyNextSampleBuffer];


    NSLog(@"READING");

    if(buffer)
        [videoWriterInput appendSampleBuffer:buffer];

    NSLog(@"WRITTING...");


}


//Finish the session:
[videoWriterInput markAsFinished];  
[videoWriter finishWriting];
NSLog(@"Write Ended");

}

I made it myself. Check it out:

- (void) resizeVideo:(NSURL *)videoPath outputPath:(NSURL *)outputPath
{

NSURL *fullPath = outputPath;

NSURL *path = videoPath;


NSLog(@"Write Started");

NSError *error = nil;

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:fullPath fileType:AVFileTypeQuickTimeMovie error:&error];    
NSParameterAssert(videoWriter);

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt:100], AVVideoWidthKey,
                               [NSNumber numberWithInt:100], AVVideoHeightKey,
                               nil];

AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput
                                         assetWriterInputWithMediaType:AVMediaTypeVideo
                                         outputSettings:videoSettings] retain];

NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);

videoWriterInput.expectsMediaDataInRealTime = NO;

[videoWriter addInput:videoWriterInput];




AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:path options:nil];
NSError *aerror = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset error:&aerror];


AVAssetTrack *videoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0];

NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:videoOptions];    

[reader addOutput:asset_reader_output];


[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
[reader startReading];

CMSampleBufferRef buffer;


while ( [reader status]==AVAssetReaderStatusReading )
{
    if(![videoWriterInput isReadyForMoreMediaData])
        continue;

    buffer = [asset_reader_output copyNextSampleBuffer];


    NSLog(@"READING");

    if(buffer)
        [videoWriterInput appendSampleBuffer:buffer];

    NSLog(@"WRITTING...");


}


//Finish the session:
[videoWriterInput markAsFinished];  
[videoWriter finishWriting];
NSLog(@"Write Ended");

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