0
我需要減少使用混合應用拍攝的視頻的尺寸而不降低分辨率,因此我試圖修改cordova video editor plugin以通過更改比特率來減少視頻的尺寸。 我試圖使用SDAVAssetExportSession沒有任何成功,並獲得噸的CVPixel錯誤。 插件代碼爲:在AVAsset修改cordova的比特率視頻編輯器
- (void) transcodeVideo:(CDVInvokedUrlCommand*)command
{
NSDictionary* options = [command.arguments objectAtIndex:0];
if ([options isKindOfClass:[NSNull class]]) {
options = [NSDictionary dictionary];
}
NSString *assetPath = [options objectForKey:@"fileUri"];
NSString *videoFileName = [options objectForKey:@"outputFileName"];
CDVQualityType qualityType = ([options objectForKey:@"quality"]) ? [[options objectForKey:@"quality"] intValue] : LowQuality;
NSString *presetName = Nil;
switch(qualityType) {
case HighQuality:
presetName = AVAssetExportPresetHighestQuality;
break;
case MediumQuality:
default:
presetName = AVAssetExportPresetMediumQuality;
break;
case LowQuality:
presetName = AVAssetExportPresetLowQuality;
}
CDVOutputFileType outputFileType = ([options objectForKey:@"outputFileType"]) ? [[options objectForKey:@"outputFileType"] intValue] : MPEG4;
BOOL optimizeForNetworkUse = ([options objectForKey:@"optimizeForNetworkUse"]) ? [[options objectForKey:@"optimizeForNetworkUse"] intValue] : NO;
float videoDuration = [[options objectForKey:@"duration"] floatValue];
BOOL saveToPhotoAlbum = [options objectForKey:@"saveToLibrary"] ? [[options objectForKey:@"saveToLibrary"] boolValue] : YES;
NSString *stringOutputFileType = Nil;
NSString *outputExtension = Nil;
switch (outputFileType) {
case QUICK_TIME:
stringOutputFileType = AVFileTypeQuickTimeMovie;
outputExtension = @".mov";
break;
case M4A:
stringOutputFileType = AVFileTypeAppleM4A;
outputExtension = @".m4a";
break;
case M4V:
stringOutputFileType = AVFileTypeAppleM4V;
outputExtension = @".m4v";
break;
case MPEG4:
default:
stringOutputFileType = AVFileTypeMPEG4;
outputExtension = @".mp4";
break;
}
// remove file:// from the assetPath if it is there
assetPath = [[assetPath stringByReplacingOccurrencesOfString:@"file://" withString:@""] mutableCopy];
// check if the video can be saved to photo album before going further
if (saveToPhotoAlbum && !UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(assetPath))
{
NSString *error = @"Video cannot be saved to photo album";
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error ] callbackId:command.callbackId];
return;
}
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *tempVideoPath =[NSString stringWithFormat:@"%@/%@%@", docDir, videoFileName, @".mov"];
NSData *videoData = [NSData dataWithContentsOfFile:assetPath];
[videoData writeToFile:tempVideoPath atomically:NO];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:tempVideoPath] options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName: presetName];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *videoPath = [NSString stringWithFormat:@"%@/%@%@", [paths objectAtIndex:0], videoFileName, outputExtension];
exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
exportSession.outputFileType = stringOutputFileType;
exportSession.shouldOptimizeForNetworkUse = optimizeForNetworkUse;
NSLog(@"videopath of your file: %@", videoPath);
if (videoDuration)
{
int32_t preferredTimeScale = 600;
CMTime startTime = CMTimeMakeWithSeconds(0, preferredTimeScale);
CMTime stopTime = CMTimeMakeWithSeconds(videoDuration, preferredTimeScale);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.timeRange = exportTimeRange;
}
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) {
case AVAssetExportSessionStatusCompleted:
if (saveToPhotoAlbum) {
UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, nil, nil);
}
NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error);
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:videoPath] callbackId:command.callbackId];
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[[exportSession error] localizedDescription]] callbackId:command.callbackId];
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Export canceled");
break;
default:
NSLog(@"Export default in switch");
break;
}
}];
}
}
我怎麼能實現科爾多瓦插件裏面AVAssetWriter?
NSDictionary *settings = @{AVVideoCodecKey:AVVideoCodecH264,
AVVideoWidthKey:@(video_width),
AVVideoHeightKey:@(video_height),
AVVideoCompressionPropertiesKey:
@{AVVideoAverageBitRateKey:@(desired_bitrate),
AVVideoProfileLevelKey:AVVideoProfileLevelH264Main31, /* Or whatever profile & level you wish to use */
AVVideoMaxKeyFrameIntervalKey:@(desired_keyframe_interval)}};
AVAssetWriterInput* writer_input = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings];
我真的不需要靈活的解決方案,硬編碼很好。 我不是一個真正的Object-C專家(我發現它是一個相當晦澀的語言)
你爲什麼不問作者做出改變?其他人也有可能需要這種靈活性。 – JesseMonroy650