iOS (기능)
[SWIFT] mov 파일을 mp4 파일로 변환하기 / 동영상 재생시간 구하기(double to dateformat)
겸손할 겸
2018. 1. 30. 17:11
[로직]
동영상을 선택하란 로직에서 리턴값으로 넘어오는 값의 확장자는 .mov확장자다.
문제는 이런 동영상 파일은 아이폰에서는 정상 작동하지만, 안드로이드에서는 재생할 수 없다(물론 해당 코덱을 가진 유료 동영상 플레이어를 내장한 기기에서는 재생가능)
이럴 때 필요한 것이 서로 다른 디바이스에서 공통적으로 인식 가능하도록 확장자를 변경하여 저장하는 방법이다.
[코드]
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).first 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, 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) DispatchQueue.main.async { ... } 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).") } }
temp.mp4란 파일이 있다면 삭제하고, rendered-Video.mp4란 파일의 유무도 판단하여 삭제한다.
전자는 자주 사용하는 문구라서 혹시나 싶어 삭제하는건가 싶기도하고, 후자는 저 이름으로 mp4 파일을 만들 것이기 때문에, 기존 것을 삭제하기 위함이다.
그리고 AVAssetExprtSession이란 변환 객체를 이용하여 변환하는 것이고, 이 결과는 비동기적으로 나오기 때문에, 추가작업이 필요하다면 메인 쓰레드에서 비동기로 작업하는 것이다.
[추가]
해당 파일의 동영상 시간을 분:초로 표기하고 싶을때 사용하는 코드다.
let filePathURL = NSURL.fileURL(withPath: filePath) let asset = AVURLAsset(url: filePathURL as URL) let playTimeFloat = CMTimeGetSeconds(asset.duration) let playTimeSum = (playTimeFloat*100).rounded()/100 let minute = Int(playTimeSum / 60) let second = Int((playTimeSum.truncatingRemainder(dividingBy: 60)).rounded()) let playTime = String(format: "%0d:%02d", minute, second)