Forum Xamarin.iOS

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Process AVAsset to upload video to server

I have built up a list by getting the files of type video from a custom album as shown below. No problems there.

foreach(var asset in PHFetchResult)
{
    manager.RequestAvAsset(asset, videoOptions,
                (video, optionParams, handler) =>                     
                    {          
                        fileName = asset.ValueForKey((NSString)"filename");
                        videos.Add(video);  //List<AVAsset> (this is filtered by: asset.MediaType == PHAssetMediaType.Video)                        
                    });
}

What I need to understand is what to do with them next, as I want to upload them to a server.

With images, I can just do UIIMage.AsPNG, add that into a Stream and send it off to the server.

Could someone please give an example of the process with video files?

Best Answer

  • Ryn9011Ryn9011 Member ✭✭
    Accepted Answer

    Changed the path to below and seems to work

    var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    var tmp = Path.Combine(documents, "tmp") + ".MOV";

                        var outputURL = new NSUrl(tmp);                        
    
                        NSError error = new NSError();
    
                        AVAssetExportSession export = new AVAssetExportSession(images[i].AVAsset, AVAssetExportSessionPreset.LowQuality);                        
                        export.OutputFileType = AVFileType.QuickTimeMovie;
                        export.ShouldOptimizeForNetworkUse = true;
                        export.OutputUrl = NSUrl.FromFilename(outputURL.ToString());
    
    
                        NSFileManager.DefaultManager.Remove(outputURL, out error);
    
                        export.ExportTaskAsync();
                        Stream exportStream = File.OpenRead(tmp);
    

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    Actually this is a question about how to convert AVAsset to Stream , you could use AVAssetExportSession to compress the file save it into disk and then get stream from the path .

    Refer to the sample code : https://stackoverflow.com/a/50010110/8187800 .

        var asset = AVAsset.FromUrl(NSUrl.FromFilename(path));
        AVAssetExportSession exportSession = new AVAssetExportSession(asset, AVAssetExportSessionPreset.HighestQuality);
    
        exportSession.OutputUrl = NSUrl.FromFilename(pathService.GetCompressedPath());
        exportSession.OutputFileType = AVFileType.Mpeg4;
        exportSession.ShouldOptimizeForNetworkUse = true;
    
        await exportSession.ExportTaskAsync(); //This can cause an error so check the status
    
        Stream exportStream = File.OpenRead(path);
    
        return exportStream;
    
  • Ryn9011Ryn9011 Member ✭✭

    @ColeX thanks for your reply. I tried to do this but am getting this error:

    "Error Domain=AVFoundationErrorDomain Code=-11823 \"Cannot Save\" UserInfo={NSLocalizedRecoverySuggestion=Try saving again., NSLocalizedDescription=Cannot Save, NSUnderlyingError=0x600000904ba0 {Error Domain=NSOSStatusErrorDomain Code=-12101 \"(null)\"}}"

    other forums say to remove at the outputUrl, which I tried below, but still getting the error

    var outputPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    var outputURL = new NSUrl(outputPath);
    NSError error = new NSError();

                        AVAssetExportSession export = new AVAssetExportSession(images[i].AVAsset, AVAssetExportSessionPreset.LowQuality);                        
                        export.OutputFileType = AVFileType.QuickTimeMovie;
                        export.ShouldOptimizeForNetworkUse = true;
                        export.OutputUrl = NSUrl.FromFilename(outputURL.ToString() + ".MOV");
    
                        NSFileManager.DefaultManager.Remove(outputURL, out error); 
    
                        export.ExportAsynchronously(() =>
                        {                            
                            System.Diagnostics.Debug.WriteLine(export.Error.Description);
                            System.Diagnostics.Debug.WriteLine(export.Error.DebugDescription);                            
                            System.Diagnostics.Debug.WriteLine(export.Error.LocalizedDescription);
                            Stream exportStream = File.OpenRead(path);
                        }
    
  • Ryn9011Ryn9011 Member ✭✭

    I just made it closer to your example and gives an access denied error. Is there something wrong with this path?

    {System.UnauthorizedAccessException: Access to the path '/Users/myname/Library/Developer/CoreSimulator/Devices/43B8D0B5-0CD2-4217-A3E6-8E33348B25AB/data/Containers/Data/Application/3E4B81B5-7FD1-4896-8D78-3365A9B4BAD7/Documents' is denied.
    at System.IO.…}

    var outputPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    var outputURL = new NSUrl(outputPath);
    NSError error = new NSError();

                        AVAssetExportSession export = new AVAssetExportSession(images[i].AVAsset, AVAssetExportSessionPreset.LowQuality);                        
                        export.OutputFileType = AVFileType.QuickTimeMovie;
                        export.ShouldOptimizeForNetworkUse = true;
                        export.OutputUrl = NSUrl.FromFilename(outputURL.ToString() + ".MOV");
    
                        NSFileManager.DefaultManager.Remove(outputURL, out error);
    
                        export.ExportTaskAsync();
                        Stream exportStream = File.OpenRead(outputPath);
    
  • Ryn9011Ryn9011 Member ✭✭
    Accepted Answer

    Changed the path to below and seems to work

    var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    var tmp = Path.Combine(documents, "tmp") + ".MOV";

                        var outputURL = new NSUrl(tmp);                        
    
                        NSError error = new NSError();
    
                        AVAssetExportSession export = new AVAssetExportSession(images[i].AVAsset, AVAssetExportSessionPreset.LowQuality);                        
                        export.OutputFileType = AVFileType.QuickTimeMovie;
                        export.ShouldOptimizeForNetworkUse = true;
                        export.OutputUrl = NSUrl.FromFilename(outputURL.ToString());
    
    
                        NSFileManager.DefaultManager.Remove(outputURL, out error);
    
                        export.ExportTaskAsync();
                        Stream exportStream = File.OpenRead(tmp);
    
Sign In or Register to comment.