YPImagePicker
YPImagePicker copied to clipboard
mp4 fileType Configuration does not work
Describe the bug We use YPImagePicker in our iOS App to generate a video. The video is then uploaded to a Firebase storage.
We use the Firestore share function to share the video later on.
It turns out that .mov videos do not play in Google Chrome Browser.
Therefore we set the YPImagePicker Configuration to be an .mp4 video fileType - and its quality to AVAssetExportPresetHighestQuality.
However, it turns out that the YPImagePicker-generated video is still not quite a regular .mp4 - at least the Chrome Browser does not play it !
When we program a proper .mp4 video encoding after the YPImagePicker video-acquisition, then everything works.
However, we do not want to keep this extra .mp4 encoding method in my App since this consumes an awful lot of time. I would much rather have the YPImagePicker generate a proper.mp4 fileformat in the first place!
The fact that Google Chrome Browser won't play a YPImagePicker-generated video tells me that the YPImagePicker's .mp4 config is still corrupt. (see older bug-report where people described a similar problem).
For example, if I examine the YPImagePicker-generated .mp4 video - it turns out that the mimeType is still shown as video/quicktime instead of video/mp4. And maybe other things are still corrupt.
I suspect that the .mp4 fileType definition in YPImagePicker-config setting has no effect (or not a complete effect) on the video file generation. The YPImagePicker-generated .mp4 file is clearly not an fully correct .mp4 file but rather a messy something.
This is how I set the YPImagePicker configuration. Please note the fileType and compression-quality :
var config = YPImagePickerConfiguration()
config.onlySquareImagesFromCamera = false
config.showsCrop = .none
config.showsVideoTrimmer = true
config.showsPhotoFilters = false
config.shouldSaveNewPicturesToAlbum = false
config.albumName = "MyCompany"
config.screens = [.library, .photo, .video]
config.library.mediaType = .photoAndVideo
config.library.isSquareByDefault = false
config.video.fileType = AVFileType.mp4
config.video.compression = AVAssetExportPresetHighestQuality
config.video.recordingTimeLimit = videoMaxDuration
config.video.libraryTimeLimit = 1800.0
config.video.trimmerMaxDuration = videoMaxDuration
Is it possible that Apple's newest iOS-13.7 version did mess up anything here - or did the .mp4 conversion inside YPImagePicker never work at all ??
Any idea on how we can fix this ?
@StephanKornerTrihow thanks for such a detailed report, this is very appreciated. Time is very limited at the moment (quite bombarded with Xcode12 related issues). Could you try to investigate a fix on your side?
From my side, no time for a fix as well. Such an iOS update always puts some time-limits to everybody.
As a workarround, I do the .mp4 encoding myself with the following method (see below).
Maybe this is helpful for you to eventually integrate it into YPImagePicker.
func videoEncodeMP4(videoURL: URL, completion: @escaping (_ outputURL: URL) -> Void) {
let tempDirectory: URL
do {
tempDirectory = try FileManager.default.url(for: .itemReplacementDirectory, in: .userDomainMask, appropriateFor: videoURL, create: true)
}
catch {
log.error("Could not create temporary directory: \(error)")
return
}
let tempFileName = UUID().uuidString + ".mp4"
let tempFileURL = tempDirectory.appendingPathComponent(tempFileName)
let startDate = Date()
let asset = AVURLAsset(url: videoURL)
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
return
}
exportSession.outputURL = tempFileURL
exportSession.outputFileType = AVFileType.mp4
exportSession.shouldOptimizeForNetworkUse = true
let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
let range = CMTimeRange(start: start, duration: asset.duration)
exportSession.timeRange = range
exportSession.exportAsynchronously {
switch exportSession.status {
case .failed:
log.error("MP4 export failed: \(exportSession.error?.localizedDescription ?? "-")")
case .cancelled:
log.error("MP4 export cancelled")
case .completed:
let endDate = Date()
let time = endDate.timeIntervalSince(startDate)
log.info("MP4 output completed in \(time)s")
completion(exportSession.outputURL ?? tempFileURL)
default:
break
}
}
}
Any news to the .mp4 conversion of videos ? In your application, it turns out that we really would like to have video's being able to show in Chrome Browser. Right now, this still does not work.