ios - AVAssetWriter 可以透明写入文件吗?

标签 ios avfoundation avassetwriter avasset

如果我包含的图像没有填满整个渲染区域,我用 AVAssetWriter 编写的每个文件都有黑色背景。有什么方法可以写透明吗?这是我用来获取像素缓冲区的方法:

- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image {

    CGSize size = self.renderSize;

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVPixelBufferPoolCreatePixelBuffer(NULL, self.adaptor.pixelBufferPool, &pxbuffer);

    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
                                          size.width,
                                          size.height,
                                          kCVPixelFormatType_32ARGB,
                                          (__bridge CFDictionaryRef) options,
                                          &pxbuffer);


    if (status != kCVReturnSuccess){
        NSLog(@"Failed to create pixel buffer");
    }

    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                                 size.height, 8, 4*size.width, rgbColorSpace,
                                                 (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);

    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                           CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}

和 AVAssetWriter 代码:

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               [NSNumber numberWithInt:self.renderSize.width], AVVideoWidthKey,
                               [NSNumber numberWithInt:self.renderSize.height], AVVideoHeightKey,
                               nil];

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

NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
self.adaptor = [AVAssetWriterInputPixelBufferAdaptor
                    assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
                    sourcePixelBufferAttributes:bufferAttributes];

buffer = [self pixelBufferFromCGImage:[stickerImage CGImage]];

BOOL append_ok = YES;
    int j = 0;
    while (append_ok && j < totalFrames) {
        if (self.adaptor.assetWriterInput.readyForMoreMediaData)  {

            CMTime frameTime = CMTimeMake(frameCount,(int32_t) fps);
            append_ok = [self.adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
            if(!append_ok){
                NSError *error = self.assetWriter.error;
                if(error!=nil) {
                    NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
                }
            }
        }
        else {
            printf("adaptor not ready %d, %d\n", frameCount, j);
            [NSThread sleepForTimeInterval:0.1];
        }
        j++;
        frameCount++;
    }
    if (!append_ok) {
        printf("error appending image %d times %d\n, with error.", frameCount, j);
    }

最佳答案

简而言之,这是不可能的。 AVAssetWriter 使用 h264 视频编解码器输出。 h264 视频编解码器不支持 alpha channel ,因此您很不幸。

一个更复杂的解决方案是将 alpha channel (透明度)渲染成灰度 h264 编码视频,并在观看时将摩擦和 alpha 信息组合在一起。

关于ios - AVAssetWriter 可以透明写入文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21538729/

相关文章:

ios - UIButtons 在动画期间没有响应 - iOS Swift 3

ios - 用数字按字母顺序对数组进行排序

iphone - 使用 AVPlayer 和 AVAssetExportSession 进行缓存

ios - iOS 上的 MLKit 文本检测适用于从 Assets.xcassets 拍摄的照片,但不适用于相机拍摄/从相机胶卷上传的同一张照片

ios - 在后台检测 MPMusicPlayerController 通知

ios - 如何从录制的视频中提取音频?

ios - Mapview - 防止发现坐标为零

ios - 如何将 YouTube V3 API 集成到 iOS 项目中?

iphone - AVAssetWriterInput H.264 直通到 QuickTime (.mov) - 传入 SPS/PPS 以创建 avcC 原子?

iphone - 如何使用iOS SDK修剪视频文件并转换为15秒视频?