Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
295 views
in Technique[技术] by (71.8m points)

ios - Swift - How to record video in MP4 format with UIImagePickerController?

I am creating a app in which i need to record videos and upload it to a server. Now my project has a android version too. To support android version i have to record the videos in mp4 format. I followed this tutorial to set the UIImagePicker media type to movie format imagePicker.mediaTypes = [kUTTypeMovie as String]

The UIImagePickerController is perfect for my requirement and the only thing that i need to change is its saving format to mp4. I tried kUTTypeMPEG4 in mediaTypes but it throws error at the run time with no error description.

This is my video Capture function

func startCameraFromViewController() {

        if UIImagePickerController.isSourceTypeAvailable(.Camera) == false {
            return
        }
        viewBlack.hidden = false
        presentViewController(cameraController, animated: false, completion: nil)

        cameraController.sourceType = .Camera

        cameraController.mediaTypes = [kUTTypeMovie as String]
        //cameraController.mediaTypes = [kUTTypeMPEG4 as String]
        cameraController.cameraCaptureMode = .Video
        cameraController.videoQuality = .TypeMedium
        if(getPurchaseId() as! Int == 0)
        {
            if(txtBenchMark.text?.isEmpty == false)
            {
                cameraController.videoMaximumDuration = NSTimeInterval(300.0)
            }else{
                cameraController.videoMaximumDuration = NSTimeInterval(60.0)
            }
        }else{
            cameraController.videoMaximumDuration = NSTimeInterval(600.0)
        }
        cameraController.allowsEditing = false
    }

I am using Swift 2.2 and Xcode 8 with Use Legacy swift Language version = Yes

Any Alternative Solutions are also appreciated. Thanks in advance.

EDIT: I found out that there is no method to directly record videos in mp4 format in swift. only can be converted to required format from apple's quicktime mov format.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I made some modifications to the following 2 answers to make it compatible with Swift 5:
https://stackoverflow.com/a/40354948/2470084
https://stackoverflow.com/a/39329155/2470084

import AVFoundation

func encodeVideo(videoURL: URL){
    let avAsset = AVURLAsset(url: videoURL)
    let startDate = Date()
    let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough)
    
    let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    let myDocPath = NSURL(fileURLWithPath: docDir).appendingPathComponent("temp.mp4")?.absoluteString
    
    let docDir2 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as NSURL
    
    let filePath = docDir2.appendingPathComponent("rendered-Video.mp4")
    deleteFile(filePath!)
    
    if FileManager.default.fileExists(atPath: myDocPath!){
        do{
            try FileManager.default.removeItem(atPath: myDocPath!)
        }catch let error{
            print(error)
        }
    }
    
    exportSession?.outputURL = filePath
    exportSession?.outputFileType = AVFileType.mp4
    exportSession?.shouldOptimizeForNetworkUse = true
    
    let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
    let range = CMTimeRange(start: start, duration: avAsset.duration)
    exportSession?.timeRange = range
    
    exportSession!.exportAsynchronously{() -> Void in
        switch exportSession!.status{
        case .failed:
            print("(exportSession!.error!)")
        case .cancelled:
            print("Export cancelled")
        case .completed:
            let endDate = Date()
            let time = endDate.timeIntervalSince(startDate)
            print(time)
            print("Successful")
            print(exportSession?.outputURL ?? "")
        default:
            break
        }
        
    }
}

func deleteFile(_ filePath:URL) {
    guard FileManager.default.fileExists(atPath: filePath.path) else{
        return
    }
    do {
        try FileManager.default.removeItem(atPath: filePath.path)
    }catch{
        fatalError("Unable to delete file: (error) : (#function).")
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...