Compress video size before attach to an email in swift

我们两清 提交于 2019-12-04 05:21:19

问题


Previous, I have ask for how to attach video then send via email. Now it working. Advised by some friend from this website.

I found new problem that video size is very large and larger than send with default email app in iOS for same video file.

Please advice me how to compress video file before attach to an email application.

Thank you everyone.

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {

    if let myImage = info[UIImagePickerControllerOriginalImage] as? UIImage {

        image = info[UIImagePickerControllerOriginalImage] as! UIImage
        self.dismissViewControllerAnimated(false, completion: nil)
        sendmail()

    }
    else {
        //picker.videoQuality = UIImagePickerControllerQualityTypeLow
        videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
        self.dismissViewControllerAnimated(true, completion: nil)
        sendmailVDO()
    }

}

回答1:


Below is the code for Compress video by half of the actual size

var assetWriter:AVAssetWriter?
var assetReader:AVAssetReader?
let bitrate:NSNumber = NSNumber(value:250000)

func compressFile(urlToCompress: URL, outputURL: URL, completion:@escaping (URL)->Void){
    //video file to make the asset

    var audioFinished = false
    var videoFinished = false

    let asset = AVAsset(url: urlToCompress);

    let duration = asset.duration
    let durationTime = CMTimeGetSeconds(duration)

    print("Video Actual Duration -- \(durationTime)")

    //create asset reader
    do{
        assetReader = try AVAssetReader(asset: asset)
    } catch{
        assetReader = nil
    }

    guard let reader = assetReader else{
        fatalError("Could not initalize asset reader probably failed its try catch")
    }

    let videoTrack = asset.tracks(withMediaType: AVMediaType.video).first!
    let audioTrack = asset.tracks(withMediaType: AVMediaType.audio).first!

    let videoReaderSettings: [String:Any] =  [(kCVPixelBufferPixelFormatTypeKey as String?)!:kCVPixelFormatType_32ARGB ]

    // ADJUST BIT RATE OF VIDEO HERE

    let videoSettings:[String:Any] = [
        AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:self.bitrate],
        AVVideoCodecKey: AVVideoCodecType.h264,
        AVVideoHeightKey: videoTrack.naturalSize.height,
        AVVideoWidthKey: videoTrack.naturalSize.width
    ]


    let assetReaderVideoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
    let assetReaderAudioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)


    if reader.canAdd(assetReaderVideoOutput){
        reader.add(assetReaderVideoOutput)
    }else{
        fatalError("Couldn't add video output reader")
    }

    if reader.canAdd(assetReaderAudioOutput){
        reader.add(assetReaderAudioOutput)
    }else{
        fatalError("Couldn't add audio output reader")
    }

    let audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil)
    let videoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
    videoInput.transform = videoTrack.preferredTransform
    //we need to add samples to the video input

    let videoInputQueue = DispatchQueue(label: "videoQueue")
    let audioInputQueue = DispatchQueue(label: "audioQueue")

    do{
        assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileType.mov)
    }catch{
        assetWriter = nil
    }
    guard let writer = assetWriter else{
        fatalError("assetWriter was nil")
    }

    writer.shouldOptimizeForNetworkUse = true
    writer.add(videoInput)
    writer.add(audioInput)


    writer.startWriting()
    reader.startReading()
    writer.startSession(atSourceTime: kCMTimeZero)


    let closeWriter:()->Void = {
        if (audioFinished && videoFinished){
            self.assetWriter?.finishWriting(completionHandler: {
                print("------ Finish Video Compressing")
                self.checkFileSize(sizeUrl: (self.assetWriter?.outputURL)!, message: "The file size of the compressed file is: ")

                completion((self.assetWriter?.outputURL)!)
            })

            self.assetReader?.cancelReading()
        }
    }


    audioInput.requestMediaDataWhenReady(on: audioInputQueue) {
        while(audioInput.isReadyForMoreMediaData){
            let sample = assetReaderAudioOutput.copyNextSampleBuffer()
            if (sample != nil){
                audioInput.append(sample!)
            }else{
                audioInput.markAsFinished()
                DispatchQueue.main.async {
                    audioFinished = true
                    closeWriter()
                }
                break;
            }
        }
    }

    videoInput.requestMediaDataWhenReady(on: videoInputQueue) {
        //request data here
        while(videoInput.isReadyForMoreMediaData){
            let sample = assetReaderVideoOutput.copyNextSampleBuffer()
            if (sample != nil){
                let timeStamp = CMSampleBufferGetPresentationTimeStamp(sample!)
                let timeSecond = CMTimeGetSeconds(timeStamp)
                let per = timeSecond / durationTime
                print("Duration --- \(per)")
                DispatchQueue.main.async {
                    self.progress.progress = Float(per)
                }
                videoInput.append(sample!)
            }else{
                videoInput.markAsFinished()
                DispatchQueue.main.async {
                    videoFinished = true
                    self.progress.progress = 1.0
                    closeWriter()
                }
                break;
            }
        }
    }
}

You can also display the progress of video compression.



来源:https://stackoverflow.com/questions/32113831/compress-video-size-before-attach-to-an-email-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!