标签:
注:实际上视频文件的Rotation元数据并不是保存的角度值,不过如果只关心角度问题而不是图像拉伸之类的,可以这样简单理解。关于如何获取Rotation元数据角度值,有兴趣的可以参看 vlc的源码。
//…...
NSString * url = @"http://www.yourdomain.com/Videos/1.m3u8";
MPMoviePlayerViewController * vc = [[MPMoviePlayerViewController alloc] init];
vc.moviePlayer.contentURL = [NSURL URLWithString:url];
// 这里播放一个Rotation为90的视频,即Home键在下录制的视频
[self rotateVideoView:vc degrees:90];
[self presentMoviePlayerViewControllerAnimated:vc];
[vc.moviePlayer play];
//…...
- (void)rotateVideoView:(MPMoviePlayerViewController *)movePlayerViewController degrees:(NSInteger)degrees
{
if(degrees==0||degrees==360) return;
if(degrees<0) degrees = (degrees % 360) + 360;
if(degrees>360) degrees = degrees % 360;
// MPVideoView在iOS8中Tag为1002,不排除苹果以后更改的可能性。参考递归查看View层次结构的lldb命令: (lldb) po [movePlayerViewController.view recursiveDescription]
UIView *videoView = [movePlayerViewController.view viewWithTag:1002];
if ([videoView isKindOfClass:NSClassFromString(@"MPVideoView")]) {
videoView.transform = CGAffineTransformMakeRotation(M_PI * degrees / 180.0);
videoView.frame = movePlayerViewController.view.bounds;
}
}
改为Category:
#import "MPMoviePlayerViewController+Rotation.h"
@implementation MPMoviePlayerViewController (Rotation)
- (void)rotateVideoViewWithDegrees:(NSInteger)degrees
{
if(degrees==0||degrees==360) return;
if(degrees<0) degrees = (degrees % 360) + 360;
if(degrees>360) degrees = degrees % 360;
// MPVideoView在iOS8中Tag为1002,不排除苹果以后更改的可能性。参考递归查看View层次结构的lldb命令: (lldb) po [movePlayerViewController.view recursiveDescription]
UIView *videoView = [self.view viewWithTag:1002];
if ([videoView isKindOfClass:NSClassFromString(@"MPVideoView")]) {
videoView.transform = CGAffineTransformMakeRotation(M_PI * degrees / 180.0);
videoView.frame = self.view.bounds;
}
}
@end
注:如果愿意,写入非0、90、180或270的值,比如45之类的也是可以的。
+ (NSUInteger)degressFromVideoFileWithURL:(NSURL *)url
{
NSUInteger degress = 0;
AVAsset *asset = [AVAsset assetWithURL:url];
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
if([tracks count] > 0) {
AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
CGAffineTransform t = videoTrack.preferredTransform;
if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0){
// Portrait
degress = 90;
}else if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0){
// PortraitUpsideDown
degress = 270;
}else if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0){
// LandscapeRight
degress = 0;
}else if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0){
// LandscapeLeft
degress = 180;
}
}
return degress;
}
+ (UIImage *)extractImageFromVideoFileWithUrl:(NSURL *)url
{
NSDictionary *opts = @{AVURLAssetPreferPreciseDurationAndTimingKey:@(NO)};
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:opts];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
// 应用方向
gen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(1, 60);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
if(error)
{
DLog(@"%@ %@",__FUNCTION_FILE_LINE__,error);
return nil;
}
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
return thumb;
}
注:这种涉及大量内存拷贝的操作,实际应用中要权衡其利弊。以下代码未经过测试。
1、RGB24旋转90度
// RGB24旋转90度
void RGB24Rotate90(int8_t *des, const int8_t *src, int width, int height)
{
if(!des || !src) return;
int n = 0;
int linesize = width * 3;
int i, j;
// 逆时针旋转
for (j = width; j > 0; j--) {
for (i = 0; i < height; i++) {
memccpy(&des[n], &src[linesize * i + j * 3 - 3], 0, 3);
n += 3;
}
}
/*
// 顺时针旋转
for (j = 0 ; j < width; j++) {
for (i = height; i > 0; i--) {
memccpy(&des[n], &src[linesize * (i - 1) + j * 3 - 3], 0, 3);
n += 3;
}
}
*/
}
2、RGB24旋转90度
// YUV420旋转90度
void YUV420Rotate90(int8_t *des, const int8_t *src, int width, int height)
{
int i = 0, j = 0, n = 0;
int hw = width / 2, hh = height / 2;
const int8_t *ptmp = src;
for (j = width; j > 0; j--) {
for (i = 0; i < height; i++) {
des[n++] = ptmp[width * i + j];
}
}
ptmp = src + width * height;
for (j = hw; j > 0; j--) {
for (i = 0; i < hh; i++) {
des[n++] = ptmp[hw * i + j];
}
}
ptmp = src + width * height * 5 / 4;
for (j = hw; j > 0; j--) {
for (i = 0; i < hh; i++) {
des[n++] = ptmp[hw * i + j];
}
}
}
或:
int8_t[] rotateYUV420Degree90(int8_t[] data, int imageWidth, int imageHeight)
{
int8_t [] yuv = new int8_t[imageWidth*imageHeight*3/2];
// Rotate the Y luma
int i = 0;
for(int x = 0;x < imageWidth;x++)
{
for(int y = imageHeight-1;y >= 0;y--)
{
yuv[i] = data[y*imageWidth+x];
i++;
}
}
// Rotate the U and V color components
i = imageWidth*imageHeight*3/2-1;
for(int x = imageWidth-1;x > 0;x=x-2)
{
for(int y = 0;y < imageHeight/2;y++)
{
yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+x];
i--;
yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)];
i--;
}
}
return yuv;
}
标签:
原文地址:http://my.oschina.net/are1OfBlog/blog/501228