2016-11-01 8 views
8

私はビデオを録画してサーバーにアップロードする必要があるアプリを作成しています。今私のプロジェクトはアンドロイド版も持っています。 Android版をサポートするには、動画をmp4形式で録画する必要があります。私はUIImagePickerControllerは私の要件に最適ですし、私は変更する必要がある唯一のものは、MP4への保存形式であるimagePicker.mediaTypes = [kUTTypeMovie as String]スイフト - UIImagePickerControllerでビデオをMP4形式で記録するには?

ムービー形式にUIImagePickerメディアタイプを設定するthisチュートリアルを追いました。私はkUTTypeMPEG4mediaTypesにしようとしましたが、エラーの説明なしで実行時にエラーをスローします。

これは私が任意の代替ソリューションも高く評価されUse Legacy swift Language version = Yes

でスウィフト2.2とXcode 8を使用しています、私のビデオキャプチャ機能

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 
    } 

です。前もって感謝します。

編集: すぐにmp4形式でビデオを直接録画する方法がないことを知りました。 appleのquicktime mov形式から必要な形式にのみ変換できます。

ここ

答えて

3

あなたはMP4に録画したビデオを変換するために使用できるいくつかのコードです:

func encodeVideo(videoURL: NSURL) { 
let avAsset = AVURLAsset(URL: videoURL, options: nil) 

var startDate = NSDate() 

//Create Export session 
exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) 

// exportSession = AVAssetExportSession(asset: composition, presetName: mp4Quality) 
//Creating temp path to save the converted video 


let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] 
let myDocumentPath = NSURL(fileURLWithPath: documentsDirectory).URLByAppendingPathComponent("temp.mp4").absoluteString 
let url = NSURL(fileURLWithPath: myDocumentPath) 

let documentsDirectory2 = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL 

let filePath = documentsDirectory2.URLByAppendingPathComponent("rendered-Video.mp4") 
deleteFile(filePath) 

//Check if the file already exists then remove the previous file 
if NSFileManager.defaultManager().fileExistsAtPath(myDocumentPath) { 
    do { 
     try NSFileManager.defaultManager().removeItemAtPath(myDocumentPath) 
    } 
    catch let error { 
     print(error) 
    } 
} 

url 

exportSession!.outputURL = filePath 
exportSession!.outputFileType = AVFileTypeMPEG4 
exportSession!.shouldOptimizeForNetworkUse = true 
var start = CMTimeMakeWithSeconds(0.0, 0) 
var range = CMTimeRangeMake(start, avAsset.duration) 
exportSession.timeRange = range 

exportSession!.exportAsynchronouslyWithCompletionHandler({() -> Void in 
    switch self.exportSession!.status { 
    case .Failed: 
     print("%@",self.exportSession?.error) 
    case .Cancelled: 
     print("Export canceled") 
    case .Completed: 
     //Video conversion finished 
     var endDate = NSDate() 

     var time = endDate.timeIntervalSinceDate(startDate) 
     print(time) 
     print("Successful!") 
     print(self.exportSession.outputURL) 

    default: 
     break 
    } 

}) 


} 

func deleteFile(filePath:NSURL) { 
guard NSFileManager.defaultManager().fileExistsAtPath(filePath.path!) else { 
    return 
} 

do { 
    try NSFileManager.defaultManager().removeItemAtPath(filePath.path!) 
}catch{ 
    fatalError("Unable to delete file: \(error) : \(__FUNCTION__).") 
} 
} 

出典:https://stackoverflow.com/a/39329155/4786204

+0

ありがとうございます。やってみます。しかし、あなたは私が直接mp4形式でカメラからビデオを記録することができる方法を知っていますか? –

+0

私はそれがUI画像ピッカーで可能であるとは思わない。 –

+0

あなたのお友達にありがとう。私は上記のコードを試してみます。 –

10

私はSwift3と互換性を持たせるために、次の2件の回答にいくつかの変更をしました
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 = AVFileTypeMPEG4 
    exportSession?.shouldOptimizeForNetworkUse = true 

    let start = CMTimeMakeWithSeconds(0.0, 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).") 
    } 
} 
+0

おかげでスウィフト3バージョン –

0

iOS11で実行すると、AVAssetExportSessionのnil値が常に表示されます。この場合の解決策はありますか?

if let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) { 
    //work on iOS 9 and 10 
} else { 
    //always on iOS 11 
} 
関連する問題