导出带有AVMutableComposition的镜像视频会导致尺寸调整问题 [英] Exporting a mirrored video with AVMutableComposition causes resizing issues

查看:169
本文介绍了导出带有AVMutableComposition的镜像视频会导致尺寸调整问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我关闭前置摄像头的镜像,一切都会按预期进行.但是,如果我打开它,则最终导出的视频会出现严重的尺寸调整问题:

Everything works as expected if I turn off the mirroring on the front camera. However, if I turn it on, my final exported video has crucial resizing problems:

这是我当前如何管理视频镜像的方式:

This is how I currently manage the mirroring for my videos:

       if currentDevice == frontCamera {

            if let connection = output.connections.first {
                if connection.isVideoMirroringSupported {
                    connection.automaticallyAdjustsVideoMirroring = false
                    connection.isVideoMirrored = true //if true, this bug occurs.
                }
            }


        }else {
             //disabling photo mirroring on backCamera
            if let connection = output.connections.first {
                if connection.isVideoMirroringSupported {
                    connection.automaticallyAdjustsVideoMirroring = false
                    connection.isVideoMirrored = false
                }
            }
        }

这就是我导出视频的方式:

And this is how I export the video:

  /// Create AVMutableComposition object. This object will hold the AVMutableCompositionTrack instances.

let mainMutableComposition = AVMutableComposition()
        /// Creating an empty video track
        let videoTrack = mainMutableComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
        let videoAssetTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]

        do {
            //Adding the video track
            try videoTrack?.insertTimeRange(CMTimeRange(start: kCMTimeZero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaType.video).first!, at: kCMTimeZero)

        } catch {
            completion(false,  nil)
        }

        /// Adding audio if user wants to.
        if withAudio {
            do {
                //Adding the video track
                let audio = videoAsset.tracks(withMediaType: AVMediaType.audio).first
                if audio != nil {
                    let audioTrack = mainMutableComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
                    try audioTrack?.insertTimeRange(CMTimeRange(start: kCMTimeZero, duration: videoAsset.duration), of: audio!, at: kCMTimeZero)

                }

            } catch {
                completion(false,  nil)
            }

        }

        // * MARK - Composition is ready ----------

        // Create AVMutableVideoCompositionInstruction
        let compositionInstructions = AVMutableVideoCompositionInstruction()
        compositionInstructions.timeRange = CMTimeRange(start: kCMTimeZero, duration: videoAsset.duration)

        // Create an AvmutableVideoCompositionLayerInstruction
        let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction.init(assetTrack: videoTrack!)
        videoLayerInstruction.setTransform(videoAssetTrack.preferredTransform, at: kCMTimeZero)
        compositionInstructions.layerInstructions = [videoLayerInstruction]

        //Add instructions
        let videoComposition = AVMutableVideoComposition()

        let naturalSize : CGSize = videoAssetTrack.naturalSize

        ///Rendering image into video
        let renderWidth = naturalSize.width
        let renderHeight = naturalSize.height

        //Assigning instructions and rendering size
        videoComposition.renderSize = CGSize(width: renderWidth, height: renderHeight)
        videoComposition.instructions = [compositionInstructions]
        videoComposition.frameDuration = CMTime(value: 1, timescale: Int32((videoTrack?.nominalFrameRate)!))

        //Applying image to instruction
        self.applyVideoImage(to: videoComposition, withSize: naturalSize, image: image)

        // Getting the output path
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
        let outputPath = documentsURL?.appendingPathComponent("lastEditedVideo.mp4")
        if FileManager.default.fileExists(atPath: (outputPath?.path)!) {
            do {
                try FileManager.default.removeItem(atPath: (outputPath?.path)!)
            }
            catch {
                completion(false, nil)
            }
        }



        // Create exporter
        let exporter = NextLevelSessionExporter(withAsset: mainMutableComposition)
        exporter.outputURL = outputPath
        exporter.outputFileType = AVFileType.mp4
        exporter.videoComposition = videoComposition

        let compressionDict: [String: Any] = [
            AVVideoAverageBitRateKey: NSNumber(integerLiteral: 2300000),
            AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel as String
            ]

        exporter.videoOutputConfiguration = [
            AVVideoCodecKey: AVVideoCodecType.h264,
            AVVideoWidthKey: NSNumber(integerLiteral: Int(naturalSize.width)),
            AVVideoHeightKey: NSNumber(integerLiteral: Int(naturalSize.height)),
            AVVideoCompressionPropertiesKey: compressionDict
        ]

        exporter.audioOutputConfiguration = [
            AVFormatIDKey: kAudioFormatMPEG4AAC,
            AVEncoderBitRateKey: NSNumber(integerLiteral: 128000),
            AVNumberOfChannelsKey: NSNumber(integerLiteral: 2),
            AVSampleRateKey: NSNumber(value: Float(44100))
        ]

        completion(true, exporter)
    }

我正在使用NextLevelSessionExporter导出视频.不管是否使用默认导出器,大小调整问题仍然会发生.

I'm using the NextLevelSessionExporter to export the video. It doesn't matter if I use the default exporter or not, the resizing problems still occur.

推荐答案

存在一个活动的错误,阻止您正确导出镜像的视频.您需要一些解决方法:

There is an active bug that prevents you from exporting mirrored videos correctly. You need a few workarounds:

  1. 关闭movieOutputFile上的镜像
  2. 在需要时手动将视频水平翻转:

  1. Turn off the mirroring on the movieOutputFile
  2. Manually flip the video horizontally when needed:

if needsMirroring == true {

    var transform:CGAffineTransform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    transform = transform.translatedBy(x: -naturalSize.width, y: 0.0)
    transform = transform.rotated(by: CGFloat(Double.pi/2))
    transform = transform.translatedBy(x: 0.0, y: -naturalSize.width)
    videoTransform = transform
}

我花了几天时间才弄清楚这一点,希望对您有所帮助.

It took me days to figure this out, hope it helps.

这篇关于导出带有AVMutableComposition的镜像视频会导致尺寸调整问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆