@astorphobis Does it work when you 1) take a pair of working HEIC & MOV, 2) Re-encode the MOV, 3) Copy over the metadata from the original video to the new video?
I forgot to mention that I've also tried to create my own, custom live wallpaper with the same result.
I have, however, little to no experience with video formats, encoding etc., so I tried my best yet I still failed. Haven't tried re-encoding the MOV, I have, however, tried to copy metadata over from video in
Pair 1 to video in
Pair 2 and then try to combine the new video with photo from
Pair 1, but that didn't work neither.
In the meantime, I managed to get at least something working - I combined the code that was mentioned before with the QuickTimeHelper to copy over the metadata and actually
this is now able to create a custom live photo, it, however, says that motion is not supported. A little step towards the goal.
PS: The code is a mess, I was experimenting (hence the name) and just trying to figure it out, and didn't bother with tidying it up or anything.
PPS: "Lights" is one of the working - tested pairs of Photo + Video, "Wave" is some random stock footage encoded in HEIC, and this combines the "Lights.HEIC" image and "Wave.MOV" video. It should also copy over metadata from "Lights.MOV", but I haven't had time to confirm that yet, will look into it over the weekend.
Swift:
func DoMagicStuff() {
// MAGIC STUFF HERE
Log(string: "Loading ...")
guard let imageFileURL = Bundle.main.url(forResource: "Lights", withExtension: "HEIC"),
let videoFileURL = Bundle.main.url(forResource: "Lights", withExtension: "MOV"),
let test1FileURL = Bundle.main.url(forResource: "Wave", withExtension: "MOV")
else {
Log(string: "Error: File is nil")
return
}
Log(string: "Loaded image \(imageFileURL)")
Log(string: "Loaded video \(videoFileURL)")
let twilightHelper = QuickTimeHelper(path: videoFileURL.path)
let test1Helper = QuickTimeHelper(path: test1FileURL.path)
guard let assetIdentifier = twilightHelper.readAssetIdentifier() else {
Log(string: "Error: Unable to read asset identifier")
return
}
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destURL = documentDirectory.appendingPathComponent("Test1_Updated.MOV")
test1Helper.write(destURL.path, assetIdentifier: assetIdentifier)
let photoLibrary = PHPhotoLibrary.shared()
Log(string: "Performing changes...")
photoLibrary.performChanges({
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, fileURL: imageFileURL, options: nil)
creationRequest.addResource(with: .pairedVideo, fileURL: destURL, options: nil)
}, completionHandler: { success, error in
if success {
Log(string: "Live Photo saved successfully!")
} else if let error = error {
Log(string: "Error saving Live Photo to the library: \(error.localizedDescription)")
}
})
}