Xamarin Tips and Tricks – Compressing Videos in Xamarin.Forms Projects

(Originally published 3/29/17)

Today I will be starting a series of Xamarin programming tips and tricks that I have learned from different projects I have worked on. Lets kick this off with platform specific video compression in Xamarin.Forms. Since media encoding is done differently on iOS and Android, we need to write different solutions for Forms projects. We will be taking a look at iOS media compression today. Our media will be picked using Xamarin’s Media Plugin (Plugin.Media), which delivers the picked media in a MediaFile object. We will then pass this object into our compression method which will then send it back out as a file stream. You can view a gist of the method involved below:


public async Task<Stream> CompressVideo(MediaFile file)
{
string exportPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string exportFilePath = Path.Combine(exportPath, "compressed_video.mp4");
System.Diagnostics.Debug.WriteLine("Export path: " + exportPath);
System.Diagnostics.Debug.WriteLine("Export file path: " + exportFilePath);
var asset = AVAsset.FromUrl(NSUrl.FromFilename(file.Path));
AVAssetExportSession export = new AVAssetExportSession(asset, AVAssetExportSessionPreset.MediumQuality);
System.Diagnostics.Debug.WriteLine("Created export object");
export.OutputUrl = NSUrl.FromFilename(exportFilePath);
export.OutputFileType = AVFileType.Mpeg4;
export.ShouldOptimizeForNetworkUse = true;
System.Diagnostics.Debug.WriteLine("Preparing to export");
await runExportAsync(export);
Stream exportStream = File.OpenRead(exportFilePath);
System.Diagnostics.Debug.WriteLine("Stream read from file");
return exportStream;
}
private async Task RunExportAsync(AVAssetExportSession exp)
{
await exp.ExportTaskAsync();
if (exp.Status == AVAssetExportSessionStatus.Completed)
{
System.Diagnostics.Debug.WriteLine("Finished export");
}
}

view raw

gist.cs

hosted with ❤ by GitHub

Your MediaFile will have its uncompressed mov file taken out of it, encoded again with higher compression at a lower resolution using the native AVAssetExportSession, and sent back out as a stream. All of this runs in async and is fast on new(ish) iOS devices. You can change the amount of compression applied by modifying the export preset as well as change what type of object the file gets sent back out as (a stream is the easiest to work with especially if you are planning on uploading the file to a web service). These methods can be easily dropped into a platform specific class using a dependency service to call upon it when needed. Also note that you will have to create a public interface for this as well.

 

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s