Отсутствует звук при воспроизведении видео с помощью AVFoundation в iOS - PullRequest
0 голосов
/ 07 января 2019

Создание обратного видео с использованием avfoundation, все работает нормально. Но audio отсутствует после завершения записи. Даже для обработки видео требуется время (не более 20 секунд).

Я попробовал приведенный ниже код, чтобы сделать видео наоборот,

// Initialize the reader
NSError *error;
// check input path
if (![[NSFileManager defaultManager] fileExistsAtPath:inputPath]) {
    [self.delegate didFinishReverse:NO withError:nil];
    return;
}

[[NSFileManager defaultManager] removeItemAtPath:outputPath error:nil];

NSURL *inputUrl = [NSURL fileURLWithPath:inputPath isDirectory:NO];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputUrl options:nil];;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:nil];
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] lastObject];

NSDictionary *readerOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange], kCVPixelBufferPixelFormatTypeKey,
                                      nil];
AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack
                                                                                    outputSettings:readerOutputSettings];
[reader addOutput:readerOutput];
[reader startReading];

NSMutableArray *samples = [[NSMutableArray alloc] init];

CMSampleBufferRef sample;
while((sample = [readerOutput copyNextSampleBuffer])) {
    [samples addObject:(__bridge id)sample];
    CFRelease(sample);
}

NSURL *outputURL = [NSURL fileURLWithPath:outputPath isDirectory:NO];


AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:outputURL
                                                  fileType:AVFileTypeQuickTimeMovie
                                                     error:&error];


NSDictionary *videoCompressionProps = [NSDictionary dictionaryWithObjectsAndKeys:
                                       @(videoTrack.estimatedDataRate), AVVideoAverageBitRateKey,
                                       nil];

NSDictionary *writerOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                      AVVideoCodecH264, AVVideoCodecKey,
                                      [NSNumber numberWithInt:videoTrack.naturalSize.width], AVVideoWidthKey,
                                      [NSNumber numberWithInt:videoTrack.naturalSize.height], AVVideoHeightKey,
                                      videoCompressionProps, AVVideoCompressionPropertiesKey,
                                      nil];

AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo
                                                                 outputSettings:writerOutputSettings
                                                               sourceFormatHint:(__bridge CMFormatDescriptionRef)[videoTrack.formatDescriptions lastObject]];

[writerInput setExpectsMediaDataInRealTime:NO];
[writer addInput:writerInput];

AudioChannelLayout acl;
bzero( &acl, sizeof(acl));
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
NSDictionary* audioOutputSettings  = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                      [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,
                                      [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
                                      [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,
                                      [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
                                      nil];

AVAssetWriterInput *WriterAudioInput  = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
WriterAudioInput.expectsMediaDataInRealTime = YES;
if([writer canAddInput:WriterAudioInput]) {
    [writer addInput:WriterAudioInput];
}

 AVAssetWriterInputPixelBufferAdaptor *pixelBufferAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput sourcePixelBufferAttributes:nil];

[writer startWriting];
[writer startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp((__bridge CMSampleBufferRef)samples[0])];

for(NSInteger i = 0; i < samples.count; i++) {

    CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp((__bridge CMSampleBufferRef)samples[i]);

    CVPixelBufferRef imageBufferRef = CMSampleBufferGetImageBuffer((__bridge CMSampleBufferRef)samples[samples.count - i - 1]);

    while (!writerInput.readyForMoreMediaData) {
        [NSThread sleepForTimeInterval:0.1];
    }
    [pixelBufferAdaptor appendPixelBuffer:imageBufferRef
                     withPresentationTime:presentationTime];


}

[writerInput markAsFinished];
[writer finishWritingWithCompletionHandler:^(){
    [self.delegate didFinishReverse:YES withError:nil];

}];

Отлично работает. Я попытался найти в Google и в стеке, но не нашел точного решения.

Спасибо за вашу помощь.

...