AVMutableCompositionTrack在导出时颠倒

时间:2014-06-09 10:16:25

标签: objective-c video rotation avassetwriter avmutablecomposition

我正在使用视频渲染器,它使用gl_readPixels捕获openGL层(irrlicht引擎)并输出视频.mp4文件。这发生了两个阶段,第一阶段捕获视频并保存(AVAssetWriter),第二阶段拍摄保存的视频并将其与音轨(AVMutableCompositionTrack和AVAssetExportSession)相结合。

但是,当播放此视频时(非快速时间),尽管我试图将其翻转,但它仍然显示为颠倒。

我在第二阶段尝试过使用:

AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil];

// Flip
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height);
a_compositionVideoTrack.preferredTransform = flipVertical;

可以在iPad上翻转视频(正确播放),但在复制到其他设备时,视频仍然显示为颠倒。

我还尝试使用:

翻转AVAssetWriterInput
videoInput.expectsMediaDataInRealTime = YES;
videoInput.transform = CGAffineTransformMakeScale(1, -1);

哪个也可以在苹果设备上正确翻转视频,但不能在PC,youtube,facebook上翻转。我是否缺少一个设置或标志来定义PC上的旋转?

修改: 我也在旋转右模式下使用设备(模拟器或iPad)(我最初使用左)。录制视频时,主页按钮位于右侧。但是,对于使用旋转的视频输出,对视频旋转没有影响。

编辑2:我现在也尝试翻转与上述两种变化具有相同影响的视图。

captureView.transform = CGAffineTransformMakeRotation(180.0f * M_PI / 180.0f)

2 个答案:

答案 0 :(得分:2)

我通过在glReadPixels阶段执行交换操作解决了我的问题。我之前尝试的大多数事情的问题在于它们往往只是与视频元数据一起打包而不是移动任何像素。转换功能尤其不会带来任何繁重的工作。

包含需要反转像素的其他人的代码。使用一些更优化的代码可能有更好的方法来实现这一点,如果你知道一种方法请分享!

    // OpenGL
    unsigned int* pixelBufferData = (unsigned int*)CVPixelBufferGetBaseAddress(pixelBuffer);
    glReadPixels(0, 0, self.screen.size.width, self.screen.size.height, GL_BGRA, GL_UNSIGNED_BYTE, pixelBufferData);

    unsigned int base;
    unsigned int top;
    int width = self.screen.size.width;
    int height = self.screen.size.height;
    int half_height = height / 2;
    int base_row_index = height * width;
    int top_row_index = 0;

    for(int y = 0; y < half_height; y++) {
        base_row_index -= width;
        top_row_index += width;

        for(int x = 0; x < width; x++) {
            base = pixelBufferData[top_row_index + x];
            top = pixelBufferData[base_row_index + x];
            pixelBufferData[top_row_index + x] = top;
            pixelBufferData[base_row_index + x] = base;
        }
    }

使用memcpy和两个缓冲区优化解决方案:

for (int row = 0; row < height; ++row){
    memcpy(dstBuffer + (height - row - 1) * width * 4, srcBuffer + row * width * 4, width * 4);
}

答案 1 :(得分:0)

试试这个,将preferedTransfort与比例结合使用并转换为中心变换以将视频置于正确的位置

祝你好运。

AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake([self multiplyBy16: size.width] ,[self multiplyBy16: size.height]);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];
CGAffineTransform finalTransform ;
CGAffineTransform videoTransform = clipVideoTrack.preferredTransform;

finalTransform = CGAffineTransformConcat(videoTransform,CGAffineTransformMakeTranslation("scale and translate to center transform"));

instruction.layerInstructions = [NSArray arrayWithObjects:transformer,nil];
videoComposition.instructions = [NSArray arrayWithObject: instruction];