美文网首页OC音视频
iOS MP4解码成yuv和pcm数据

iOS MP4解码成yuv和pcm数据

作者: FBLog | 来源:发表于2018-04-18 15:56 被阅读16次

    转载:https://blog.csdn.net/u011270282/article/details/53223055

    - (void)startProcessing

    {  

        previousFrameTime = kCMTimeZero;

        previousActualFrameTime = CFAbsoluteTimeGetCurrent();

        NSDictionary *inputOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

        AVURLAsset *inputAsset = [[AVURLAsset alloc] initWithURL:self.url options:inputOptions];

        GPUImageMovie __block *blockSelf = self;

        [inputAsset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler: ^{

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

                NSError *error = nil;

                AVKeyValueStatus tracksStatus = [inputAsset statusOfValueForKey:@"tracks" error:&error];

                if (tracksStatus != AVKeyValueStatusLoaded)

                {

                    return;

                }

                blockSelf.asset = inputAsset;

                [blockSelf processAsset];

                blockSelf = nil;

            });

        }];

    }

    - (AVAssetReader*)createAssetReader

    {

        NSError *error = nil;

        AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:self.asset error:&error];

        NSMutableDictionary *outputSettings = [NSMutableDictionary dictionary];

        [outputSettings setObject:@(kCVPixelFormatType_32BGRA) forKey:(id)kCVPixelBufferPixelFormatTypeKey];

        // Maybe set alwaysCopiesSampleData to NO on iOS 5.0 for faster video decoding

        AVAssetReaderTrackOutput *readerVideoTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[[self.asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] outputSettings:outputSettings];

        readerVideoTrackOutput.alwaysCopiesSampleData = NO;

        [assetReader addOutput:readerVideoTrackOutput];

        NSArray *audioTracks = [self.asset tracksWithMediaType:AVMediaTypeAudio];

        BOOL shouldRecordAudioTrack = (([audioTracks count] > 0) && (self.audioEncodingTarget != nil) );

        AVAssetReaderTrackOutput *readerAudioTrackOutput = nil;

        if (shouldRecordAudioTrack)

        {

            [self.audioEncodingTarget setShouldInvalidateAudioSampleWhenDone:YES];

            // This might need to be extended to handle movies with more than one audio track

            AVAssetTrack* audioTrack = [audioTracks objectAtIndex:0];

            NSDictionary *dic   = @{AVFormatIDKey            :@(kAudioFormatLinearPCM),

                                    AVLinearPCMIsBigEndianKey:@NO,

                                    AVLinearPCMIsFloatKey    :@NO,

                                    AVLinearPCMBitDepthKey   :@(16)

                                    };

    readerAudioTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings: dic];

            readerAudioTrackOutput.alwaysCopiesSampleData = NO;

            [assetReader addOutput:readerAudioTrackOutput];

        }

        return assetReader;

    }

    - (void)processAsset

    {

        reader = [self createAssetReader];

        AVAssetReaderOutput *readerVideoTrackOutput = nil;

        AVAssetReaderOutput *readerAudioTrackOutput = nil;

        audioEncodingIsFinished = YES;

        for( AVAssetReaderOutput *output in reader.outputs ) {

            if( [output.mediaType isEqualToString:AVMediaTypeAudio] ) {

                audioEncodingIsFinished = NO;

                readerAudioTrackOutput = output;

            }

            else if( [output.mediaType isEqualToString:AVMediaTypeVideo] ) {

                readerVideoTrackOutput = output;

            }

        }

        if ([reader startReading] == NO) 

        {

                NSLog(@"Error reading from file at URL: %@", self.url);

            return;

        }

        __unsafe_unretained GPUImageMovie *weakSelf = self;

            while (reader.status == AVAssetReaderStatusReading && (!_shouldRepeat || keepLooping))

            {

                    [weakSelf readNextVideoFrameFromOutput:readerVideoTrackOutput];

                if ( (readerAudioTrackOutput) && (!audioEncodingIsFinished) )

                {

                        [weakSelf readNextAudioSampleFromOutput:readerAudioTrackOutput];

                }

            }

            if (reader.status == AVAssetReaderStatusCompleted) {

                [reader cancelReading];

                if (keepLooping) {

                    reader = nil;

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [self startProcessing];

                    });

                } else {

                    [weakSelf endProcessing];

                }

            }

    }

    - (BOOL)readNextAudioSampleFromOutput:(AVAssetReaderOutput *)readerAudioTrackOutput;

    {

        if (reader.status == AVAssetReaderStatusReading && ! audioEncodingIsFinished)

        {

            CMSampleBufferRef audioSampleBufferRef = [readerAudioTrackOutput copyNextSampleBuffer];

            if (audioSampleBufferRef)

            {

                CFRelease(audioSampleBufferRef);

                return YES;

            }

            else

            {

            }

        }

        return NO;

    }

    - (BOOL)readNextVideoFrameFromOutput:(AVAssetReaderOutput *)readerVideoTrackOutput;

    {

        if (reader.status == AVAssetReaderStatusReading && ! videoEncodingIsFinished)

        {

            CMSampleBufferRef sampleBufferRef = [readerVideoTrackOutput copyNextSampleBuffer];

            if (sampleBufferRef)

            {

                CFRelease(sampleBufferRef);

                return YES;

            }

            else

            {

            }

        }

        return NO;

    }

    具体可以看看GPUImageMovie,从这里拿出来改一改就可以了,注意设置输出视频和音频格式为自己想要的,比如RGBA、pcm。

    相关文章

      网友评论

      本文标题:iOS MP4解码成yuv和pcm数据

      本文链接:https://www.haomeiwen.com/subject/ddavkftx.html