YPImagePicker icon indicating copy to clipboard operation
YPImagePicker copied to clipboard

mp4 fileType Configuration does not work

Open StephanKornerTrihow opened this issue 4 years ago • 3 comments

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 avatar Sep 04 '20 10:09 StephanKornerTrihow

@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?

s4cha avatar Sep 24 '20 13:09 s4cha

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

iKK001 avatar Sep 24 '20 15:09 iKK001

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.

StephanKornerTrihow avatar Oct 23 '20 15:10 StephanKornerTrihow