How to use AVAssetReader and AVAssetWriter for multiple tracks (audio and video) simultaneously?

后端 未结 3 537
名媛妹妹
名媛妹妹 2021-02-01 09:28

I know how to use AVAssetReader and AVAssetWriter, and have successfully used them to grab a video track from one movie and transcode it into another.

3条回答
  •  醉梦人生
    2021-02-01 10:04

    You can use dispatch groups!

    Check out the AVReaderWriter example for MacOSX...

    I am quoting directly from the sample RWDocument.m:

    - (BOOL)startReadingAndWritingReturningError:(NSError **)outError
    {
        BOOL success = YES;
        NSError *localError = nil;
    
        // Instruct the asset reader and asset writer to get ready to do work
        success = [assetReader startReading];
        if (!success)
            localError = [assetReader error];
        if (success)
        {
            success = [assetWriter startWriting];
            if (!success)
                localError = [assetWriter error];
        }
    
        if (success)
        {
            dispatch_group_t dispatchGroup = dispatch_group_create();
    
            // Start a sample-writing session
            [assetWriter startSessionAtSourceTime:[self timeRange].start];
    
            // Start reading and writing samples
            if (audioSampleBufferChannel)
            {
                // Only set audio delegate for audio-only assets, else let the video channel drive progress
                id  delegate = nil;
                if (!videoSampleBufferChannel)
                    delegate = self;
    
                dispatch_group_enter(dispatchGroup);
                [audioSampleBufferChannel startWithDelegate:delegate completionHandler:^{
                    dispatch_group_leave(dispatchGroup);
                }];
            }
            if (videoSampleBufferChannel)
            {
                dispatch_group_enter(dispatchGroup);
                [videoSampleBufferChannel startWithDelegate:self completionHandler:^{
                    dispatch_group_leave(dispatchGroup);
                }];
            }
    
            // Set up a callback for when the sample writing is finished
            dispatch_group_notify(dispatchGroup, serializationQueue, ^{
                BOOL finalSuccess = YES;
                NSError *finalError = nil;
    
                if (cancelled)
                {
                    [assetReader cancelReading];
                    [assetWriter cancelWriting];
                }
                else
                {
                    if ([assetReader status] == AVAssetReaderStatusFailed)
                    {
                        finalSuccess = NO;
                        finalError = [assetReader error];
                    }
    
                    if (finalSuccess)
                    {
                        finalSuccess = [assetWriter finishWriting];
                        if (!finalSuccess)
                            finalError = [assetWriter error];
                    }
                }
    
                [self readingAndWritingDidFinishSuccessfully:finalSuccess withError:finalError];
            });
    
            dispatch_release(dispatchGroup);
        }
    
        if (outError)
            *outError = localError;
    
        return success;
    }
    

提交回复
热议问题