在附加到swift中的电子邮件之前压缩视频大小

时间:2015-08-20 08:56:20

标签: xcode swift email video compression

上一篇,我已经询问如何附加视频,然后通过电子邮件发送。现在它正在运作。由本网站的一些朋友提供建议。

我发现新的问题是视频尺寸非常大且比使用iOS中的默认电子邮件应用发送的相同视频文件大。

请在连接到电子邮件应用程序之前告诉我如何压缩视频文件。

谢谢大家。

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 个答案:

答案 0 :(得分:2)

下面是将视频压缩为实际大小一半的代码

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;
            }
        }
    }
}

您还可以显示视频压缩的进度。