rs / SDAVAssetExportSession

AVAssetExportSession drop-in replacement with customizable audio&video settings
MIT License
805 stars 212 forks source link

-[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:] Cannot call method when status is 0 #45

Closed mayur43s closed 7 years ago

mayur43s commented 9 years ago

Hi I'm using the library with following configuration setting for compressing the video files:

    SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:urlAsset];
    encoder.outputFileType = AVFileTypeMPEG4;
    encoder.outputURL = TempLowerQualityFileURL;
    encoder.shouldOptimizeForNetworkUse = YES;

    CGSize size = [[[urlAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];
    NSNumber *videoWidth = @(size.width);
    NSNumber *videoHeight = @(size.height);

    NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                                videoWidth, AVVideoCleanApertureWidthKey,
                                                videoHeight, AVVideoCleanApertureHeightKey,
                                                [NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey,
                                                [NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey,
                                                nil];

    NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithInt:1960000], AVVideoAverageBitRateKey,
                                   [NSNumber numberWithInt:24],AVVideoMaxKeyFrameIntervalKey,
                                   videoCleanApertureSettings, AVVideoCleanApertureKey,
                                   nil];

    NSDictionary *videoCompressionSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                              AVVideoCodecH264, AVVideoCodecKey,
                                              codecSettings,AVVideoCompressionPropertiesKey,
                                              videoWidth, AVVideoWidthKey,
                                              videoHeight, AVVideoHeightKey,
                                              nil];

    encoder.videoSettings = videoCompressionSettings;

It is crashing at -exportAsynchronouslyWithCompletionHandler: on line no 214 which is: [self.audioInput requestMediaDataWhenReadyOnQueue:self.inputQueue usingBlock:

But when I try to replace the above line: encoder.outputFileType = AVFileTypeMPEG4; with encoder.outputFileType = AVFileTypeQuickTimeMovie;

It works but size of the compressed video is getting increased by 200% or more.

cbedoya commented 9 years ago

Hey Mayur

I was having the same problem. Seems like if you don't specify the audioSettings it crashes! I copied all the example and just modified it with my configuration and it worked.

Hope it helps

mayur43s commented 9 years ago

Hey Cbedoya,

Yes you are right. When we don't pass audioSettings dictionary then it crashes.

SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:urlAsset];
encoder.outputFileType = AVFileTypeMPEG4;
    encoder.outputURL = TempLowerQualityFileURL;
    encoder.shouldOptimizeForNetworkUse = YES;

CGSize size = [[[urlAsset tracksWithMediaType:AVMediaTypeVideo] firstObject] naturalSize];
        NSNumber *videoWidth = @(size.width);
        NSNumber *videoHeight = @(size.height);
 encoder.videoSettings = @
    {
    AVVideoCodecKey: AVVideoCodecH264,
    AVVideoWidthKey: videoWidth,
    AVVideoHeightKey: videoHeight,
    AVVideoCompressionPropertiesKey: @
        {
        AVVideoAverageBitRateKey: @([[[urlAsset tracksWithMediaType:AVMediaTypeVideo]     firstObject] estimatedDataRate]),
        AVVideoMaxKeyFrameIntervalKey:@24,
        AVVideoProfileLevelKey: AVVideoProfileLevelH264Main30,
        },
    };
    encoder.audioSettings = @
    {
    AVFormatIDKey: @(kAudioFormatMPEG4AAC),
    AVNumberOfChannelsKey: @2,
    AVSampleRateKey: @44100,
    AVEncoderBitRateKey: @128000,
    };

For the above configuration also it doesn't compress the video instead it increases the size.

On experimenting with AVVideoAverageBitRateKey, it reduces the size but then the video exported with some black frame around it.

I've tried so many combinations but unfortunately I wasn't able to compress the video for getting the reduced size. Can you pls help me in getting the right configuration for audio and video?


Thanks Mayur

onmyway133 commented 8 years ago

This is the docs on AVAssetWriterInput convenience init(mediaType mediaType: String, outputSettings outputSettings: [String : AnyObject]?)

This is useful if, for example, you are appending buffers that are already in a desirable compressed format. However, if not writing to a QuickTime Movie file (i.e. the AVAssetWriter was initialized with a file type other than AVFileTypeQuickTimeMovie), AVAssetWriter only supports passing through a restricted set of media types and subtypes