간단한 작업이 필요합니다 : 동영상을 회전하면서 재생하고 CIFilter
을 적용하십시오.AVPlayer가 비디오 구성 결과를 잘못 재생했습니다.
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];
// DEBUG LOGGING
AVAssetTrack *track = [[item.asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
NSLog(@"Natural size is: %@", NSStringFromCGSize(track.naturalSize));
NSLog(@"Preffered track transform is: %@", NSStringFromCGAffineTransform(track.preferredTransform));
NSLog(@"Preffered asset transform is: %@", NSStringFromCGAffineTransform(item.asset.preferredTransform));
가 그럼 난 비디오 구성을 적용 할 필요가 : 첫째
, 나는 플레이어 항목을 만들 수 있습니다. 원래는 2 개의 명령어로 AVVideoComposition
을 만들려고했는데 하나는 회전을 위해 AVVideoCompositionLayerInstruction
이고 다른 하나는 CIFilter
응용 프로그램이 될 것입니다. 그러나 "AVCoreImageFilterVideoCompositionInstruction 만 포함하도록 예상되는 비디오 컴포지션"을 말하는 예외가 있습니다. 이는 Apple에서이 두 가지 명령어를 결합 할 수 없음을 의미합니다.
AVAsset *asset = playerItem.asset;
CGAffineTransform rotation = [self transformForItem:playerItem];
AVVideoComposition *composition = [AVVideoComposition videoCompositionWithAsset:asset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
// Step 1: get the input frame image (screenshot 1)
CIImage *sourceImage = request.sourceImage;
// Step 2: rotate the frame
CIFilter *transformFilter = [CIFilter filterWithName:@"CIAffineTransform"];
[transformFilter setValue:sourceImage forKey: kCIInputImageKey];
[transformFilter setValue: [NSValue valueWithCGAffineTransform: rotation] forKey: kCIInputTransformKey];
sourceImage = transformFilter.outputImage;
CGRect extent = sourceImage.extent;
CGAffineTransform translation = CGAffineTransformMakeTranslation(-extent.origin.x, -extent.origin.y);
[transformFilter setValue:sourceImage forKey: kCIInputImageKey];
[transformFilter setValue: [NSValue valueWithCGAffineTransform: translation] forKey: kCIInputTransformKey];
sourceImage = transformFilter.outputImage;
// Step 3: apply the custom filter chosen by the user
extent = sourceImage.extent;
sourceImage = [sourceImage imageByClampingToExtent];
[filter setValue:sourceImage forKey:kCIInputImageKey];
sourceImage = filter.outputImage;
sourceImage = [sourceImage imageByCroppingToRect:extent];
// Step 4: finish processing the frame (screenshot 2)
[request finishWithImage:sourceImage context:nil];
}];
playerItem.videoComposition = composition;
I 이미지가 성공적으로 회전 필터이 예에서는 (인가 보여 디버깅 중에 스크린 샷이 식별 필터했다 : 따라서, I는 모두 필터링의 여기 코드 결합 어떤 이미지를 변경하지 않습니다).
당신이 회전에 성공, 볼 수 있듯이, 그 결과 프레임의 범위 : 다음은 위의 의견에 표시된 지점에서 촬영 한 스크린 샷 1 스크린 샷이 있습니다 또한 정확했다.
플레이어에서이 비디오를 재생하려고하면 문제가 발생합니다. 모든 프레임 크기를 조절하고 아래로 이동하는 것처럼
그래서 것 같다 여기에 내가 무엇을 얻을 수 있습니다. 녹색 영역은 빈 프레임 정보입니다. 프레임 크기를 무한대로 설정하면 녹색 대신 테두리 픽셀이 표시됩니다.
이Natural size is: {1920, 1080}
Preffered track transform is: [0, 1, -1, 0, 1080, 0]
Preffered asset transform is: [1, 0, 0, 1, 0, 0]
플레이어입니다 : 내가 왜 첫 번째 코드 조각에서 나는 크기와 변환을 기록했다 위에 그건, 플레이어는 여전히 AVPlayerItem
에서 회전하기 전에 오래된 크기 정보 걸리는 느낌이, 로그있다 다음과 같이 설정 :이 장치 만 저장에 풍경에 아이폰 [기가] 방향을 카메라 를 사용하여 응용 프로그램 자체에 의해 기록되고 저장된 동영상을 발생합니다
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.needsDisplayOnBoundsChange = YES;
가장 중요한 것은 참고 사항 미리 우리. 앱이 인물 모드로 녹화하는 동영상은 완전히 괜찮습니다 (그런데 인물 사진의 크기가 똑같고 풍경 비디오와 같은 로그를 변형합니다! 이상한 ... 어쩌면 아이폰은 동영상에 회전 정보를 넣고 수정합니다). 따라서 비디오를 확대/축소하고 이동하는 것은 회전하기 전에 "화면 채우기"와 오래된 해상도 정보의 조합처럼 보입니다. 그런데 종횡비가 다른 플레이어 영역을 채우기 위해 크기 조정을하기 때문에 세로 비디오 프레임이 부분적으로 표시되지만 이는 예상되는 동작입니다.
내 생각을 알려주세요. 내가 원하는 것을 성취하는 더 좋은 방법을 안다면, 알아두면 좋을 것입니다.