Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVAssetWriterInput error when saving to device using SVAssetExportSession #80

Closed
jp-src opened this issue Nov 11, 2014 · 13 comments
Closed

Comments

@jp-src
Copy link

jp-src commented Nov 11, 2014

First of all, thank you considerably for this library, including the Xamarin bindings ;)

I am basically trying to reproduce parts of the examples you have provided in Xamarin.iOS.
However, I get an error when trying to save a video with a filter to my library.

I get the following error when using the ExportAsynchronously method of the export session:

MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSInternalInconsistencyException Reason: *** -[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:] Cannot call method when status is 0

Any help would be greatly appreciated.

@rFlex
Copy link
Owner

rFlex commented Nov 11, 2014

Hey Jerome,

I will need at least a stacktrace so I can try figuring out what happened :)

@jp-src
Copy link
Author

jp-src commented Nov 11, 2014

Sorry it was a little late last night and I didn't give you much info.

  at (wrapper managed-to-native) ApiDefinition.Messaging:void_objc_msgSend_IntPtr (intptr,intptr,intptr)
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0001c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:45 

I am using the latest version of Xamarin, with iOS SDK 8.1

screen shot 2014-11-11 at 3 12 25 pm

Here is the code I am using that causes the problem. The IF statement works well, I am able to successfully use MergeRecordSegments. The content of the ELSE statement is where I can't seem to make it work. It gives the same error as soon as I use ExportAsynchronously method.

UIApplication.SharedApplication.BeginIgnoringInteractionEvents();
            var currentFilter = filterSwitcherView.SelectedFilterGroup;

            if (currentFilter == null)
            {
                RecordSession.MergeRecordSegments(RecordSessionSegmentMerged);
            }
            else
            {
                var exportSession = new SCAssetExportSession(RecordSession.AssetRepresentingRecordSegments);
                exportSession.FilterGroup = currentFilter;
                exportSession.OutputUrl = RecordSession.OutputUrl;
                exportSession.OutputFileType = AVFileType.Mpeg4;
//                exportSession.UseGPUForRenderingFilters = true;
                exportSession.ExportAsynchronously(() =>
                {
                    RecordSessionSegmentMerged(exportSession.Error);
                });

            }

Thank you for your help !

@jp-src
Copy link
Author

jp-src commented Dec 2, 2014

Hello rFlex,

if I were to build a simple test project using Xamarin, would you have the ability to test it on your side? Or maybe you already have an example project using Xamarin?

I'm really stuck and cannot seem to figure out why. It appears the status 0 for [AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:] is "unknown", which doesn't help much...

@rFlex
Copy link
Owner

rFlex commented Dec 2, 2014

Sorry about that, I totally forgot actually. Can you try using the very last build? I made some big changes recently.

@jp-src
Copy link
Author

jp-src commented Dec 2, 2014

It's the first thing I try as soon as you commit to the repository ;)
I just retested with the latest files and still having the same issue, same error message.

There are however differences between the code you put in your Examples and the one I am using in Xamarin, as I do not have access to some of the properties you're using. Not sure if that could cause an issue...

Thanks for replying so fast !

@rFlex
Copy link
Owner

rFlex commented Dec 2, 2014

Which properties you do not have access too?

@rFlex
Copy link
Owner

rFlex commented Dec 2, 2014

If you have a simple example project on Xamarin that shows your issue I would love to have it!

@jp-src
Copy link
Author

jp-src commented Dec 2, 2014

Great, I'll write up the simple Xamarin example and send it later today!

@jp-src
Copy link
Author

jp-src commented Dec 3, 2014

Hello,

please find below the zip containing the solution for the test project.
You will have to hold the button to record one - or more - segments, then click on "Next" to move to the next page. Swipe will apply filters. Pressing the save button will work without filters, but crash when a filter is applied.

https://www.dropbox.com/s/abyw9tmz9mcvap0/SCRecorderTestProject.zip?dl=0

@rFlex
Copy link
Owner

rFlex commented Dec 3, 2014

Thank you so much for the project! It was way quicker to find the issue ;).
On your side, you forgot to set the videoSettings AND the videoSettings (or you can use the sessionPreset if you don't need fine tunings). On my side, I forgot to check and send back an error if someone forgot those.

@jp-src
Copy link
Author

jp-src commented Dec 3, 2014

Thanks !!
The error message is now much more understandable ;)

However, if I try to use the member "sessionPreset", it seems it is not available on the Xamarin side after I make the DLL. That's what I meant when I said I didn't feel I had access to some members. When I try to recreate your example in Xamarin, I tried to use

exportSession.sessionPreset = SCAssetExportSessionPresetHighestQuality;

but without success.

I'll be trying to use "refined" audioSettings by looking at your code and let you know if I finally make it work.

@jp-src
Copy link
Author

jp-src commented Dec 3, 2014

It worked like a charm when I added both Video and Audio settings !

Thanks so much.

Code I used to make it work:

var sampleRate = 44100;
var audioBitrate = 128000;
var channels = 2;

var width = 720;
var height = 720;
var videoBitrate = width*height;

var videoSettings = NSDictionary.FromObjectsAndKeys(
    new NSObject[]
    {
        AVVideo.CodecH264,
        NSNumber.FromDouble(width),
        NSNumber.FromDouble(height),
        NSDictionary.FromObjectsAndKeys(new NSObject[] {NSNumber.FromDouble(videoBitrate)},
            new NSObject[] {AVVideo.AverageBitRateKey})
    },
    new NSObject[]
    {
        AVVideo.CodecKey,
        AVVideo.WidthKey,
        AVVideo.HeightKey,
        AVVideo.CompressionPropertiesKey
    });

var audioSettings = NSDictionary.FromObjectsAndKeys(
    new NSObject[]
    {
        NSNumber.FromInt32((int) AudioFormatType.MPEG4AAC),
        NSNumber.FromInt32(sampleRate),
        NSNumber.FromInt32(audioBitrate),
        NSNumber.FromInt32(channels)
    },
    new NSObject[]
    {
        AVAudioSettings.AVFormatIDKey,
        AVAudioSettings.AVSampleRateKey,
        AVAudioSettings.AVEncoderBitRateKey,
        AVAudioSettings.AVNumberOfChannelsKey
    });

exportSession.AudioSettings = audioSettings;
exportSession.VideoSettings = videoSettings;

@rFlex
Copy link
Owner

rFlex commented Dec 4, 2014

Alright awesome ;)

@rFlex rFlex closed this as completed Dec 4, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants