2015-11-27 2 views
1

При попытке перекодировать MOV на MP4 с помощью SDAVAssetExportSession с примером из readme, я получаю границы слева и справа с помощью устройства задней камеры и квадратную обрезку с передней камерой.Странное поведение обрезки

Без какого-либо повторного кодирования мой плеер (PBJVideoPlayerController, используя AVLayerVideoGravityResizeAspectFill) корректно отображает полноэкранное видео.

Я предполагаю, что что-то не так с renderSize SDAVAssetExportSession, но я действительно не понимаю, почему у кого-то еще нет проблемы.

Вот скриншоты с передней и задней камеры после перекодирования:

Скриншот видео без перекодирования, камера заднего вида (отлично весь экран): Screenshot of video without re-encoding, rear camera (perfectly fullscreen)

Скриншот видео с перекодирования, задняя камера: Screenshot of video with re-encoding, rear camera

Скриншот видео с повторного кодирования, передняя камера Screenshot of video with re-encoding, front camera

Как вы можете видеть, плеер не должен быть проблемой, так как все нормально, без повторного кодирования. Но после экспорта границы появляются сзади, а я-не знаю-действительно-знаю-что происходит с передней камерой ...

Любая помощь?

Спасибо!

PS: Как мой кофейник?

ответ

1

Я также использую SDAVAssetExportSession, и я понял, что будет происходить плохая видеосъемка, если вы придадите портретному видео больше ширины, чем высота, и отклонитесь от требуемого соотношения сторон. То же самое произойдет и для пейзажного видео, если вы придаете ему больше высоты, чем ширина.

Мое решение состоит в том, чтобы сначала получить соотношение сторон видео и текущие размеры перед транскодированием, а затем рассчитать меньшую ширину и высоту, исходя из его текущих размеров, чтобы поддерживать соотношение сторон. Это приведет к тому, что получающееся видео будет иметь черные границы.

Update: Вот соответствующий код -

Это показывает, как изменить размер и сохранить пропорции и избежать проблем с кадрирования. Обратите внимание, что width и height являются целыми переменными, контролируемыми пользователем. Если они не предоставляются, я перекодирую с исходной шириной и высотой видео.

AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:assetPath] options:nil]; 

NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSString *outputPath = [NSString stringWithFormat:@"%@/%@%@", cacheDir, videoFileName, outputExtension]; 
NSURL *outputURL = [NSURL fileURLWithPath:outputPath]; 

NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeVideo]; 
AVAssetTrack *track = [tracks objectAtIndex:0]; 
CGSize mediaSize = track.naturalSize; 

float videoWidth = mediaSize.width; 
float videoHeight = mediaSize.height; 
float aspectRatio = videoWidth/videoHeight; 
int newWidth = (width && height) ? height * aspectRatio : videoWidth; 
int newHeight = (width && height) ? newWidth/aspectRatio : videoHeight; 

NSLog(@"input videoWidth: %f", videoWidth); 
NSLog(@"input videoHeight: %f", videoHeight); 
NSLog(@"output newWidth: %d", newWidth); 
NSLog(@"output newHeight: %d", newHeight); 

SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:avAsset]; 
encoder.outputFileType = stringOutputFileType; 
encoder.outputURL = outputURL; 
encoder.videoSettings = @ 
{ 
    AVVideoCodecKey: AVVideoCodecH264, 
    AVVideoWidthKey: [NSNumber numberWithInt: newWidth], 
    AVVideoHeightKey: [NSNumber numberWithInt: newHeight], 
    AVVideoCompressionPropertiesKey: @ 
    { 
     AVVideoAverageBitRateKey: [NSNumber numberWithInt: videoBitRate], 
     AVVideoProfileLevelKey: AVVideoProfileLevelH264High40 
    }, 
}; 
+0

Не проверено, но отмечено как принятый ответ, как будто это работает так, как ожидалось, именно это я и хотел, когда мне это нужно. –