将 AVAsset 读入帧并编译回视频

Posted

技术标签:

【中文标题】将 AVAsset 读入帧并编译回视频【英文标题】:Read AVAsset into frames and compile back to video 【发布时间】:2015-07-07 15:22:09 【问题描述】:

大家!我项目中的想法是收集视频,将其拆分为帧,然后逐帧应用特定效果(不是主题),然后将所有内容编译回来。

使用以下代码,我可以将视频读入帧并将它们传递到数组中:

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


我可以将所有内容放入一个数组中,但我需要将所有内容编译回视频轨道,使用原始轨道中的音频对其进行编译,然后保存。但是,我在网上找不到任何有用的信息。请帮忙!

提前致谢!

【问题讨论】:

只是想指出,在您的逐帧代码中存在一些内存泄漏。具体来说,您需要释放 CGImageRef、您的色彩空间、上下文和样本缓冲区。因此,如果您仍在使用它(或者如果其他人来使用它),请务必检查内存管理。 你真的应该考虑使用 GPUImage 来解决这个问题。 【参考方案1】:

一旦您拥有一组图像,AVAssetWriter 就是您的朋友。

【讨论】:

以上是关于将 AVAsset 读入帧并编译回视频的主要内容,如果未能解决你的问题,请参考以下文章

使用 AVAsset/AVCaptureSession 裁剪视频

Swift 5 将 AVAsset 保存到 UserDefaults

AVAsset 在 iOS 中使用图像叠加保存视频会破坏视频

Swift 3 将数据转换为 AVAsset 或 PHAsset

使用 AVFoundation 裁剪 AVAsset 视频不工作 iOS 8

在 Nativescript 应用程序中将 PHAsset/AVAsset 转换为 mp4 视频