I'm developing an plugin for MvvmCross to GetAudio from the device. But I'm getting an error in the Touch implementation. I've already took a look at here, here and here.
But nothing fixed my problem.
Well, so far I have:
var audioDelegate = new AudioDelegate();
audioDelegate.AudioAvailable = ProcessAudio;
mediaPicker = new MPMediaPickerController();
mediaPicker.Delegate = audioDelegate;
mediaPicker.AllowsPickingMultipleItems = false;
modalHost.PresentModalViewController (mediaPicker, true);
To start the picker from audio, where AudioDelegate is:
private class AudioDelegate : MPMediaPickerControllerDelegate
{
public EventHandler<MvxAudioRecorderEventArgs> AudioAvailable;
public override void MediaItemsPicked (MPMediaPickerController sender, MPMediaItemCollection mediaItemCollection)
{
if (mediaItemCollection.Count < 1)
{
return;
}
MvxAudioRecorderEventArgs eventArg = new MvxAudioRecorderEventArgs (mediaItemCollection.Items [0].AssetURL);
AudioAvailable (this, eventArg);
}
}
And then in ProcessAudio:
private void ProcessMedia(object sender, UIImagePickerMediaPickedEventArgs e)
{
var assetURL = e.MediaUrl;
NSDictionary dictionary = null;
var assetExtension = e.MediaUrl.Path.Split ('.') [1];
var songAsset = new AVUrlAsset (assetURL, dictionary);
var exporter = new AVAssetExportSession (songAsset, AVAssetExportSession.PresetPassthrough.ToString ());
exporter.OutputFileType = (assetExtension == "mp3") ? "com.apple.quicktime-movie" : AVFileType.AppleM4A;
var manager = new NSFileManager ();
var count = 0;
string filePath = null;
do
{
var extension = "mov";//( NSString *)UTTypeCopyPreferredTagWithClass(( CFStringRef)AVFileTypeQuickTimeMovie, kUTTagClassFilenameExtension);
var fileNameNoExtension = "AUD_" + Guid.NewGuid ().ToString ();
var fileName = string.Format ("{0}({1})", fileNameNoExtension, count);
filePath = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments) + "/";
filePath = filePath + fileName + "." + extension;
count++;
} while (manager.FileExists (filePath));
var outputURL = new NSUrl (filePath);//should be something in objective C... => [NSURL fileURLWithPath:filePath];
exporter.OutputUrl = outputURL;
exporter.ExportAsynchronously ( () =>
{
var exportStatus = exporter.Status;
switch (exportStatus)
{
case AVAssetExportSessionStatus.Unknown:
case AVAssetExportSessionStatus.Completed:
{
//remove the .mov from file and make it available for callback mediaAvailable()...
break;
}
case AVAssetExportSessionStatus.Waiting:
case AVAssetExportSessionStatus.Cancelled:
case AVAssetExportSessionStatus.Exporting:
case AVAssetExportSessionStatus.Failed:
default:
{
var exportError = exporter.Error;
if(assumeCancelled != null)
{
assumeCancelled();
}
break;
}
}
});
mediaPicker.DismissViewController(true, () => { });
modalHost.NativeModalViewControllerDisappearedOnItsOwn();
}
But it is always with Status.Failed with error:
LocalizedDescription: The operation could not be completed
Description: Error Domain=AVFoundationErrorDomain Code=-11800
"The operation could not be completed" UserInfo=0x1476cce0
{NSLocalizedDescription=The operation could not be completed,
NSUnderlyingError=0x1585da90 "The operation couldn’t be completed.
(OSStatus error -12780.)", NSLocalizedFailureReason=An unknown error
occurred (-12780)}
Can anyone help me? Thanks in regard,
Found the solution. As I thought the error was in the outputURL file.
Changed it to:
var count = 0;
string filePath = null;
do
{
var extension = "mp3.mov";//( NSString *)UTTypeCopyPreferredTagWithClass(( CFStringRef)AVFileTypeQuickTimeMovie, kUTTagClassFilenameExtension);
var fileNameNoExtension = "AUD_" + Guid.NewGuid ().ToString ();
var fileName = (count == 0) ? fileNameNoExtension : string.Format ("{0}({1})", fileNameNoExtension, count);
filePath = NSBundle.MainBundle.BundlePath + "/../tmp/" + fileName; /* HERE WAS THE FIRST PROBLEM, USE NSBUNDLE... */
filePath = filePath + fileName + "." + extension;
count++;
} while (manager.FileExists (filePath));
var outputURL = NSUrl.FromFilename(filePath); /* HERE WAAS THE SECOND PROBLEM, CREATE IT WITH FROMFILENAME INSTEAD OF NEW... */
And then in the export, just remove the .mov extension...
var withoutMOVPath = outputURL.Path.Remove(outputURL.Path.Length - 4);
NSError error = null;
manager.Move (outputURL.Path, withoutMOVPath, out error);
if(error != null && assumeCancelled != null)
{
assumeCancelled();
return;
}
var mediaStream = new FileStream (withoutMOVPath, FileMode.Open);
mediaAvailable (mediaStream);
break;