ios - 在 Objective-C 中使用 SCRecorder 以修改后的播放速度保存视频

标签 ios objective-c iphone playback video-recording

使用 SCRecorder 想要在录制后保存视频,用户选择不同的播放速度,例如:2x、3x。使用AVPlayer,可以使用这段代码实现:

//create mutable composition
AVMutableComposition *mixComposition = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                               preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *videoInsertError = nil;
BOOL videoInsertResult = [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                                                        ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                                                         atTime:kCMTimeZero
                                                          error:&videoInsertError];
if (!videoInsertResult || nil != videoInsertError) {
    //handle error
    return;
}

//slow down whole video by 2.0
double videoScaleFactor = 2.0;
CMTime videoDuration = asset.duration;

[compositionVideoTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, videoDuration)
                           toDuration:CMTimeMake(videoDuration.value*videoScaleFactor, videoDuration.timescale)];

//export
AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                  //   presetName:AVAssetExportPresetLowQuality];

但是,不知道如何使用 SCRecorder 库实现相同的效果。请指导。 提前致谢。

最佳答案

终于得到了我自己的答案:

- (void)SlowMotion:(NSURL *)URl
{
AVURLAsset* videoAsset = [AVURLAsset URLAssetWithURL:URl options:nil];    //self.inputAsset;

AVAsset *currentAsset = [AVAsset assetWithURL:URl];
AVAssetTrack *vdoTrack = [[currentAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
//create mutable composition
AVMutableComposition *mixComposition = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

NSError *videoInsertError = nil;
BOOL videoInsertResult = [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                                    ofTrack:[[videoAsset     tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                                                     atTime:kCMTimeZero
                                                      error:&videoInsertError];
if (!videoInsertResult || nil != videoInsertError) {
//handle error
return;
}

NSError *audioInsertError =nil;
BOOL audioInsertResult =[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                                   ofTrack:[[currentAsset    tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                                                    atTime:kCMTimeZero
                                                     error:&audioInsertError];

if (!audioInsertResult || nil != audioInsertError) {
//handle error
return;
}

CMTime duration =kCMTimeZero;
duration=CMTimeAdd(duration, currentAsset.duration);
//slow down whole video by 2.0
double videoScaleFactor = 2.0;
CMTime videoDuration = videoAsset.duration;

[compositionVideoTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, videoDuration)
                       toDuration:CMTimeMake(videoDuration.value*videoScaleFactor, videoDuration.timescale)];
[compositionAudioTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, videoDuration)
                       toDuration:CMTimeMake(videoDuration.value*videoScaleFactor, videoDuration.timescale)];
[compositionVideoTrack setPreferredTransform:vdoTrack.preferredTransform];

    NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docsDir = [dirPaths objectAtIndex:0];
    NSString *outputFilePath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"slowMotion.mov"]];
    if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
    [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
    NSURL *_filePath = [NSURL fileURLWithPath:outputFilePath];

//export
AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                    presetName:AVAssetExportPresetLowQuality];
assetExport.outputURL=_filePath;
                      assetExport.outputFileType =                AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
                       [assetExport exportAsynchronouslyWithCompletionHandler:^
                        {

                            switch ([assetExport status]) {
                                case AVAssetExportSessionStatusFailed:
                                {
                                    NSLog(@"Export session faiied with error: %@", [assetExport error]);
                                    dispatch_async(dispatch_get_main_queue(), ^{
                                        // completion(nil);
                                    });
                                }
                                    break;
                                case AVAssetExportSessionStatusCompleted:
                                {

                                    NSLog(@"Successful");
                                    NSURL *outputURL = assetExport.outputURL;

                                    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                                    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputURL]) {

                                        [self writeExportedVideoToAssetsLibrary:outputURL];
                                    }
                                    dispatch_async(dispatch_get_main_queue(), ^{
                                        //                                            completion(_filePath);
                                    });

                                }
                                    break;
                                default:

                                    break;
                            }


                        }];


 }

 - (void)writeExportedVideoToAssetsLibrary :(NSURL *)url {
NSURL *exportURL = url;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:exportURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:exportURL completionBlock:^(NSURL *assetURL, NSError *error){
    dispatch_async(dispatch_get_main_queue(), ^{
        if (error) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[error localizedDescription]
                                                                message:[error localizedRecoverySuggestion]
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
            [alertView show];
        }
        if(!error)
        {
           // [activityView setHidden:YES];
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sucess"
                                                                message:@"video added to gallery successfully"
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
            [alertView show];
        }
 #if !TARGET_IPHONE_SIMULATOR
        [[NSFileManager defaultManager] removeItemAtURL:exportURL error:nil];
 #endif
    });
}];
} else {
NSLog(@"Video could not be exported to assets library.");
}

}

关于ios - 在 Objective-C 中使用 SCRecorder 以修改后的播放速度保存视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53664242/

相关文章:

ios - 如何在 iOS 中快速使用 UDP 套接字?

objective-c - 如何从 UIWebView 中删除链接?

ios - 如果它与 iOS 11 匹配,我如何告诉 xcode 包含特定的代码块?

objective-c - UICollectionViewCell 已隐藏,但我从未将其设置为隐藏

ios - 应用程序在后台运行时如何获取室内位置X和Y位置?

ios - 可以在 iPad 上编辑 Firebase Cloud Functions 并部署更改吗?

ios - 在 iOS 中添加指向 nsattributedstrings 的链接时出现越界错误

objective-c - 我应该使用哪种类型来保存具有相同 key 的多个对象? (iOS)

iphone - 如何在按住 MenuItem 按钮时重复操作? (cocos2d)

iPhone,如何使我的工具栏与导航栏一样不透明?