ios – How can I generate a metadata.mov file for higher-resolution Dwell Photographs (e.g. 1440×2560)?

0
1
ios – How can I generate a metadata.mov file for higher-resolution Dwell Photographs (e.g. 1440×2560)?


I am producing Dwell Photographs programmatically to be used as wallpapers on iOS. I am utilizing a recognized metadata.mov file bundled with the app (doubtless extracted from a working Dwell Picture with decision 1080×1920). This setup works effective once I use a video of the identical decision.

I am utilizing this open-source library to deal with the video-to-LivePhoto conversion:
https://github.com/TouSC/Video2LivePhoto

Nevertheless, once I attempt utilizing a higher-resolution video (e.g. 2560×1440) to keep away from black bars on high-resolution units (like iPhone 14 Professional Max), the Photographs app exhibits the Dwell Picture, however the movement element does not work—it simply says “Movement Not Accessible.”

I imagine the difficulty is that the static metadata.mov comprises resolution-specific metadata, which prevents it from working accurately with different video sizes.

  • Tried altering the decision of the video (e.g. 1440×2560, 1284×2778) – movement breaks.

  • Tried producing a brand new .mov file utilizing FFmpeg with a silent video observe, matching the brand new decision – Dwell Picture not acknowledged or exhibits errors.

  • Tried modifying the present metadata.mov with instruments like FFmpeg, AtomicParsley, Bento4, and mp4box – ensuing recordsdata typically break the Dwell Picture fully.

  • I anticipated to generate a sound metadata.mov (or related observe) that might assist the customized decision and restore Dwell Picture movement assist.

static func convertVideo(videoURL: URL, full: @escaping (_ success: Bool, _ errorMessage: String?) -> Void) {
    print("begin changing")
    
    guard let metaURL = Bundle.fundamental.url(forResource: "metadata", withExtension: "mov") else {
        full(false, "metadata.mov not discovered")
        return
    }

    let livePhotoSize = CGSize(width: 1440, top: 2560) // <-- up to date decision
    let livePhotoDuration = CMTime(worth: 550, timescale: 600)
    let assetIdentifier = UUID().uuidString

    guard let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
        full(false, "Doc path not discovered")
        return
    }

    let durationPath = documentPath + "/period.mp4"
    let acceleratePath = documentPath + "/speed up.mp4"
    let resizePath = documentPath + "/resize.mp4"
    let finalPath = resizePath

    removeFileIfExists(at: durationPath)
    removeFileIfExists(at: acceleratePath)
    removeFileIfExists(at: resizePath)

    let converter = Converter4Video(path: finalPath)

    Job {
        do {
            attempt await converter.durationVideo(at: videoURL, outputPath: durationPath, targetDuration: 3)
            attempt await converter.accelerateVideo(at: durationPath, to: livePhotoDuration, outputPath: acceleratePath)
            attempt await converter.resizeVideo(at: acceleratePath, outputPath: resizePath, outputSize: livePhotoSize)

            print("### resize Success")
            let picture = attempt await generateCGImage(finalPath: finalPath)

            await generateLivePhoto(
                picture: picture,
                documentPath: documentPath,
                assetIdentifier: assetIdentifier,
                metaURL: metaURL,
                converter: converter,
                full: full
            )
        } catch {
            print("Video conversion error: (error)")
            full(false, error.localizedDescription)
            return
        }
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here