0

My iOS app using Swift 4 has the ability to save or share videos that were taken from the front or back camera. In the instance where I take a selfie video, using the front facing camera, and share the video to another application, it sends it upside down even though it saves with the correct orientation. All the necessary transforms take place before saving or sending as far as I'm aware.

Update - I found that the video is shown flipped sharing to Facebook or Messenger, but not Mail. I can still save the video and then upload it to Facebook or Messenger, and it will be in the correct orientation.

I've narrowed it down to being a difference between saving and sharing, but I don't know what it is.


Saving - Sends correct orientation

For saving, a URL is sent to my save function. assetCollection is a PHAssetCollection. A PHAssetCollectionChangeRequest takes place and the video is saved.

func save(URL: URL, completion : @escaping () -> ()) {
    if assetCollection == nil {
        print("error upstream. save skipped")
        return // if there was an error upstream, skip the save
    }

    PHPhotoLibrary.shared().performChanges({
        print("saving")
        let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL)
        let assetPlaceHolder = assetChangeRequest?.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection)
        let enumeration: NSArray = [assetPlaceHolder!]

        if self.assetCollection.estimatedAssetCount == 0
        {
            albumChangeRequest!.addAssets(enumeration)
        }
        else {
            albumChangeRequest!.insertAssets(enumeration, at: [0])
        }

    }, completionHandler: { status , error in
        completion( )
    })
}

Sharing - Sends incorrect orientation

When sharing to other apps, NSData from the video URL (self.fileURL) is written to a file path, where a new URL is created and put into the objectsToShare array.

let urlData = NSData(contentsOf: self.fileURL)

if urlData != nil {

    let paths:[String] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let docDirectory:String = paths[0]
    let filePath:String = "\(docDirectory)/tmpVideo.mp4"
    urlData?.write(toFile: filePath, atomically: true)

    let videoLink = NSURL(fileURLWithPath: filePath)
    let objectsToShare:[NSURL] = [videoLink]

    let activity: UIActivityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    DispatchQueue.main.async {
        UIApplication.topViewController?.present(activity, animated: true, completion: nil)
    }

}

Does PHPhotoLibrary preserve orientation transforms made to video, while sharing doesn't? How can I make it behave the same when sharing?

Just as a side note, I also tried saving the video to my photo library, and then choosing the video from my library in another app and sending, and the orientation is correct. Only sends upside down with my share code.


How the video is stored temporarily to be saved or shared later:

I first use a temp directory. This is to preview the video before saving or sharing. Here "url" is where I export my video, which is used by the save or share functions later.

let tempDir = NSTemporaryDirectory()
let url = NSURL(fileURLWithPath: tempDir).appendingPathComponent("tmpMov.mov")
jscs
  • 63,694
  • 13
  • 151
  • 195
Chewie The Chorkie
  • 4,896
  • 9
  • 46
  • 90

1 Answers1

2

A bit of camera lore might explain your issue

All cameras capture images upside down. This is due to how light enters the lens and hit the sensor (exhibit 1). So what you will find is that saving the video to your photo library as a PHAsset probably transforms the picture (not preserves as you theorised) to be in a correct orientation. You haven't shown the code of how you capture the video, but you might find that it is a raw capture and you do no processing on it, thus it being inverted.

Chris
  • 7,830
  • 6
  • 38
  • 72
  • I should have mentioned that I play the video inside a player within my app with no additional transforms before saving or sharing. It's in the correct orientation within the app at least. – Chewie The Chorkie Feb 15 '19 at 18:04
  • The capture code is rather complex, so maybe there's a particular part of it that would be helpful seeing? Just so that you are aware too, both sharing and saving are both available as options when the video from the URL is playing in an AVPlayer. – Chewie The Chorkie Feb 15 '19 at 18:15
  • How do you save the file to disk? Is it a raw camera capture? – Chris Feb 15 '19 at 18:18
  • See the last part of my question to see how it is stored. Please let me know if you want more info. – Chewie The Chorkie Feb 15 '19 at 18:27