Search code examples
iosxamarinxamarin.iosavcapturesession

Xamarin iOS AVCaptureSession - Only Audio/No Video on iPhone 8


We have a video recording app built with Xamarin Forms. For the iOS recording we have a custom renderer which does something like this:

        NSError error;

        var CaptureSession = new AVCaptureSession();
        CaptureSession.SessionPreset = AVCaptureSession.PresetMedium;

        var videoDevices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);
        var cameraPosition = AVCaptureDevicePosition.Front;
        var device = videoDevices.FirstOrDefault(d => d.Position == cameraPosition);
        var input = new AVCaptureDeviceInput(device, out error);
        CaptureSession.AddInput(input);

        var audioDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Audio);
        var audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice, out error);
        CaptureSession.AddInput(audioDeviceInput);

        CaptureSession.StartRunning();

        // ...
        // ...

        var MovieFileOutput = new AVCaptureMovieFileOutput();

        CaptureSession.AddOutput(MovieFileOutput);
        var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        var outputFilePath = Path.Combine(basePath, Path.ChangeExtension("video", "mov"));
        MovieFileOutput.StartRecordingToOutputFile(NSUrl.FromFilename(outputFilePath), this);

        // ...
        // ...

        MovieFileOutput.StopRecording();

We used to even just rename the .mov file to .mp4 and it played fine on all browsers - chrome on mac/pc & safari. I know this is not a good idea but it just seemed to work.

This used to work absolutely fine until iPhone 8. Now any video recorded on iPhone 8 works fine in Safari, but on chrome for mac or pc it just plays the audio but no video.

I know that apple has come with some new video/photo formats in the recent iOS release, but that should have affected iPhone 7 Plus(running the latest iOS and "High Efficiency" setting enabled in the camera).

What is a good way to encode the recorded video as a mp4 video directly so such issues dont occur?

The above code was based on the sample app - https://developer.xamarin.com/samples/monotouch/ios10/AVCam/


Solution

  • Answering this question as a couple of people seem to be facing the same issue.

    I ended up using AVExportSession to do the conversion. This seems like the best way to do the conversion though I did not find many examples on how to do this right in Xamarin.

    See below a snippet of my code:

        private void ExportToMP4()
        {
            var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            var inputFilePath = Path.Combine(basePath, "test.mov");
            var outputFilePath = Path.Combine(basePath, "test.mp4");
    
            var asset = AVAsset.FromUrl(NSUrl.FromFilename(inputFilePath));
    
            AVAssetExportSession export = new AVAssetExportSession(asset, AVAssetExportSession.PresetMediumQuality);
    
            export.OutputUrl = NSUrl.FromFilename(outputFilePath);
            export.OutputFileType = AVFileType.Mpeg4;
            export.ShouldOptimizeForNetworkUse = true;
    
            try
            {
                //Reference : https://forums.xamarin.com/discussion/62537/xamarin-ios-mov-to-mp4-conversion
                export.ExportAsynchronously(() =>
                {
                    if (export.Error != null)
                    {
                        System.Diagnostics.Debug.WriteLine(export.Error.LocalizedDescription);
                    }
                    else
                    {
                        InvokeOnMainThread(() =>
                        {
                            // Success! Do what needs to be done...
                        });
                    }
                });
    
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }