Search code examples
iosvideo-processingfile-storageios-app-group

Not able to save video from share-extension ios


I have created a share-extension whose purpose is to share videos to my container app. As part of the share flow i would like to check if user is logged in etc.. So i created an App Group and am sharing the data between the container app and the extension.( using both NSUserDefaults and Core Data)

 let  sharedUserDefaults = NSUserDefaults(suiteName:"group.app.group.name")
lazy var applicationDocumentsDirectory: NSURL = {
    NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.app.group.name")!
}()

This is working fine.

Now as i am trying to compress the video using SDAVAssetExportSession

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH-mm-ss"
let timeStamp = NSDate()
let asset = AVAsset(URL: self.shareVideoURL)
let exportSession = SDAVAssetExportSession(asset: asset)
let outputURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("\(dateFormatter.stringFromDate(timeStamp)).MP4")
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileTypeMPEG4
exportSession.shouldOptimizeForNetworkUse = true

let assetTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first!

let videoWidth:NSNumber = assetTrack.naturalSize.width, videoHeight:NSNumber = assetTrack.naturalSize.height, 
let desiredBitrate:NSNumber = 3*1024*1024 , desiredKeyFrameInterval:NSNumber = 20
exportSession.videoSettings = [AVVideoCodecKey:AVVideoCodecH264,
    AVVideoWidthKey:videoWidth,
    AVVideoHeightKey:videoHeight,
    AVVideoCompressionPropertiesKey: [
        AVVideoAverageBitRateKey:desiredBitrate,
        AVVideoMaxKeyFrameIntervalKey:desiredKeyFrameInterval]]

exportSession.audioSettings = [AVFormatIDKey: NSNumber(unsignedInt: kAudioFormatMPEG4AAC),
    AVNumberOfChannelsKey: 2,
    AVSampleRateKey: 44100,
    AVEncoderBitRateKey: 64000]

exportSession.exportAsynchronouslyWithCompletionHandler({
    switch exportSession.status {
    case .Completed:
        print("Compressed Video size : \(Double(NSData(contentsOfURL: outputURL)!.length)/(1024*1024)) mb")
    case  .Failed:
        print("Export Failed :\(exportSession.error)")
    case .Cancelled:
        print("Export Cancelled :\(exportSession.error)")
    default:
        print("complete")
    }
})         

When i execute this in the share-extension i am getting the error:

Error Domain=NSURLErrorDomain Code=-3000 "Cannot create file" 
UserInfo={NSLocalizedDescription=Cannot create file, NSUnderlyingError=0x160900450 
{Error Domain=NSOSStatusErrorDomain Code=-12149 "(null)"}}

When i run this code in another app using the document directory it is working fine without any problems, but when i start using the app group container it is not allowing to save the file.

Can anyone point me in the right direction to save the compressed file in the shared app group container


Solution

  • I couldn't find a solution for AVAssetExportSession and began to use AVAssetWriter directly, then also via SDAVAssetExportSession

    And seems like it works, it saves video. So, please check, that URL you are saving to is corresponding to this.

    i rewrote Swift code from link to Objective-C

    NSURL *groupPath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: @"group.**.***"];
    groupPath = [groupPath URLByAppendingPathComponent: @"Library" isDirectory: YES];
    groupPath = [groupPath URLByAppendingPathComponent:@"Caches" isDirectory: YES];
    

    code added after Rao's comment

    Hope you'll solve this, keep me updated.