我尝试编写一个 IOS 应用程序来了解
customVideoCompositorClass
的工作原理。
然而,在我的代码之后,我得到了一个带有正确声音的黑色视频。 sourcePixelBuffer
始终为零。我哪里错过了?
我的视频源:MPEG-4 AAC、H.264
我的代码:
#import <AVFoundation/AVFoundation.h>
#import "AAPLViewController.h"
@implementation CustomVideoCompositor
- (nullable id<AVVideoCompositionInstruction>)requiredSourceTrackIDsForFrame:(CMTime)frameTime {
return nil;
}
- (NSArray<AVVideoCompositionInstruction *> *)requiredPixelBufferAttributesForRenderContext {
return nil;
}
- (void)startVideoCompositionRequest:(AVAsynchronousVideoCompositionRequest *)request {
// Extract source pixel buffer
NSArray *a = request.sourceTrackIDs;
CVPixelBufferRef sourcePixelBuffer = [request sourceFrameByTrackID: (int)a[0]];
[request finishWithComposedVideoFrame:sourcePixelBuffer];
}
- (NSDictionary *)sourcePixelBufferAttributes {
return @{
(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)
};
}
- (void)renderContextChanged:(AVVideoCompositionRenderContext *)newRenderContext {
}
@end
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [[NSBundle mainBundle] URLForResource:@"1" withExtension:@"mov"];
AVAsset *asset = [AVAsset assetWithURL:url];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:asset];
videoComposition.customVideoCompositorClass = [CustomVideoCompositor class];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
playerItem.videoComposition = videoComposition;
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerViewController *controller = [[AVPlayerViewController alloc] init];
self.playerViewController = controller;
CGSize videoSize = [[[asset tracksWithMediaType:AVMediaTypeVideo] firstObject] naturalSize];
[self addChildViewController:controller];
[self.view addSubview:controller.view];
controller.view.frame = CGRectMake(-70, 270, videoSize.width * SCALE, videoSize.height * SCALE);
controller.view.transform = CGAffineTransformMakeRotation(M_PI_2);
controller.player = player;
controller.showsPlaybackControls = YES;
[player pause];
[player play];
}
事实证明我需要转换
TrackID
而不是直接将其转换为int
- (void)startVideoCompositionRequest:(AVAsynchronousVideoCompositionRequest *)request {
// Extract source pixel buffer
NSArray *sourceTrackIDs = request.sourceTrackIDs;
if (sourceTrackIDs.count == 0) {
NSLog(@"No source track IDs found in the request");
return;
}
CMPersistentTrackID trackID = [sourceTrackIDs[0] intValue]; // Assuming only one track ID is provided
CVPixelBufferRef sourcePixelBuffer = [request sourceFrameByTrackID: trackID];
if (!sourcePixelBuffer) {
NSLog(@"Failed to extract source pixel buffer for track ID: %d", trackID);
return;
}
[request finishWithComposedVideoFrame:sourcePixelBuffer];