更新
不要使用模拟器测试视频翻译。但我有编解码器问题 在另一个问题here中提出。任何帮助表示赞赏。
我正在使用AVURLAsset创建我的视频,只要从图库中挑选的视频处于横向模式,它们就可以正常工作。但是当我使用肖像视频时,它可以在黑屏(音频播放)中播放,或者帧被扭曲(见图像)。
更新 我尝试使用CGAffineTransform仍然没有运气。
以下是代码:
-(void) createVideo{
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSDictionary *options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES};
_videoAsset = [[AVURLAsset alloc]initWithURL:video_url options:options];
CMTime startTimeV=CMTimeMakeWithSeconds(videoStartTime.floatValue, 1);
CMTime endTimeV=CMTimeMakeWithSeconds(videoEndTime.floatValue, 1);
CMTimeRange video_timeRange = CMTimeRangeMake(startTimeV,endTimeV);
AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[_videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration);
AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:a_compositionVideoTrack];
AVAssetTrack *videoAssetTrack = [[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGSize trackDimensions = {
.width = 0.0,
.height = 0.0,
};
trackDimensions = [videoAssetTrack naturalSize];
int width = trackDimensions.width;
int height = trackDimensions.height;
UIImageOrientation videoAssetOrientation_ = UIImageOrientationUp;
BOOL isVideoAssetPortrait_ = NO;
CGAffineTransform videoTransform = videoAssetTrack.preferredTransform;
if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
videoAssetOrientation_ = UIImageOrientationRight;
isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {
videoAssetOrientation_ = UIImageOrientationLeft;
isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) {
videoAssetOrientation_ = UIImageOrientationUp;
}
if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) {
videoAssetOrientation_ = UIImageOrientationDown;
}
// CGAffineTransform transformToApply=CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90.0));
[videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
[videolayerInstruction setOpacity:0.0 atTime:self.videoAsset.duration];
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
CGSize naturalSize;
if(isVideoAssetPortrait_){
naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width);
} else {
naturalSize = videoAssetTrack.naturalSize;
}
float renderWidth, renderHeight;
renderWidth = naturalSize.width;
renderHeight = naturalSize.height;
mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight);
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
出口:
-(void)export{
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString* fileName=[NSString stringWithFormat:@"myvideo%lld.mp4",[@(floor([[NSDate date] timeIntervalSince1970])) longLongValue]+1];
NSString *outputFilePath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",fileName]];
NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.outputFileType = AVFileTypeMPEG4;
_assetExport.outputURL = outputFileUrl;
_assetExport.videoComposition = mainCompositionInst;
ShareViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"vidShare"];
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
dispatch_async(dispatch_get_main_queue(), ^{
newViewController.videoFilePath=outputFileUrl;
[self.navigationController pushViewController:newViewController animated:YES];
});
}
];
}
风景=确定
人像=失败
答案 0 :(得分:1)
我以前遇到过这个问题。在大多数情况下,使用videoAssetTrack.preferredTransform设置videolayerInstruction的变换。但有时preferredTransform可能缺乏tx(ty)的值(你应该检查CGAffineTransform在Apple API参考中,如果你不知道什么是tx(ty))或tx(ty)有不准确的值导致错误的视频定位(如在黑屏中玩。) 所以重点是:你应该使用preferredTransform来确定原始视频方向并进行自己的转换 这是获取轨道方向的代码:
- (UIInterfaceOrientation)orientationForTrack:(AVAsset *)asset {
UIInterfaceOrientation orientation = UIInterfaceOrientationPortrait;
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
if([tracks count] > 0) {
AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
CGAffineTransform t = videoTrack.preferredTransform;
// Portrait
if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0) {
orientation = UIInterfaceOrientationPortrait;
}
// PortraitUpsideDown
if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0) {
orientation = UIInterfaceOrientationPortraitUpsideDown;
}
// LandscapeRight
if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0) {
orientation = UIInterfaceOrientationLandscapeRight;
}
// LandscapeLeft
if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0) {
orientation = UIInterfaceOrientationLandscapeLeft;
}
}
return orientation;
}
用于获取所需变换以应用于videolayerInstruction的转换的代码:
- (CGAffineTransform)transformBasedOnAsset:(AVAsset *)asset {
UIInterfaceOrientation orientation = [AVUtilities orientationForTrack:asset];
AVAssetTrack *assetTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
CGSize naturalSize = assetTrack.naturalSize;
CGAffineTransform finalTranform;
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
finalTranform = CGAffineTransformMake(-1, 0, 0, -1, naturalSize.width, naturalSize.height);
break;
case UIInterfaceOrientationLandscapeRight:
finalTranform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
break;
case UIInterfaceOrientationPortrait:
finalTranform = CGAffineTransformMake(0, 1, -1, 0, naturalSize.height, 0);
break;
case UIInterfaceOrientationPortraitUpsideDown:
finalTranform = CGAffineTransformMake(0, -1, 1, 0, 0, naturalSize.width);
break;
default:
break;
}
return finalTranform;
}
希望它适合你。