将 AVAsset 读入帧并编译回视频
Read AVAsset into frames and compile back to video
大家好!我项目中的想法是收集一个视频,将其分成帧,然后逐帧应用特定效果(不是主题),然后将所有内容编译回来。
使用以下代码,我能够将视频读入帧并将它们传递到数组中:
//initialize avassetreader
AVAsset *avAsset = [AVAsset assetWithURL:url];
NSError *error = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset error:&error];
//get video track
NSArray *videoTracks = [avAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoTrack = [videoTracks objectAtIndex:0];
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:options];
[reader addOutput:asset_reader_output];
[reader startReading];
接下来,正如我上面所说,我一帧一帧地阅读轨道
//while there is something to read
while ( [reader status]==AVAssetReaderStatusReading ) {
CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// Get the number of bytes per row for the pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
//Generate image to edit
unsigned char* pixel = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
CGContextRef context=CGBitmapContextCreate(pixel, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
CGImageRef image = CGBitmapContextCreateImage(context);
UIImage* myImage = [[UIImage alloc] initWithCGImage:image];
[photos addObject:myImage];
}
我可以将所有内容放入一个数组中,但我需要将所有内容编译回视频轨道,使用原始轨道的音频进行编译,然后保存。但是,我在网上找不到任何有用的信息。请帮忙!
提前致谢!
一旦你有了图像数组,AVAssetWriter 就是你的朋友。
大家好!我项目中的想法是收集一个视频,将其分成帧,然后逐帧应用特定效果(不是主题),然后将所有内容编译回来。
使用以下代码,我能够将视频读入帧并将它们传递到数组中:
//initialize avassetreader
AVAsset *avAsset = [AVAsset assetWithURL:url];
NSError *error = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset error:&error];
//get video track
NSArray *videoTracks = [avAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoTrack = [videoTracks objectAtIndex:0];
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:options];
[reader addOutput:asset_reader_output];
[reader startReading];
接下来,正如我上面所说,我一帧一帧地阅读轨道
//while there is something to read
while ( [reader status]==AVAssetReaderStatusReading ) {
CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// Get the number of bytes per row for the pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
//Generate image to edit
unsigned char* pixel = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
CGContextRef context=CGBitmapContextCreate(pixel, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
CGImageRef image = CGBitmapContextCreateImage(context);
UIImage* myImage = [[UIImage alloc] initWithCGImage:image];
[photos addObject:myImage];
}
我可以将所有内容放入一个数组中,但我需要将所有内容编译回视频轨道,使用原始轨道的音频进行编译,然后保存。但是,我在网上找不到任何有用的信息。请帮忙!
提前致谢!
一旦你有了图像数组,AVAssetWriter 就是你的朋友。