如何更改视频方向

2024-01-05

我目前有一个 iPhone 应用程序,可以让用户拍摄视频,将其上传到服务器,并允许其他人从该应用程序查看他们的视频。从来没有遇到过视频方向的问题,直到我制作一个网站来观看不同的视频(以及其他内容)。

我使用来自网络服务的视频,并使用 videojs 通过 ajax 加载它们,但它们中的每一个都向左旋转 90 度。据我所知,方向信息似乎可以在 iOS 中读取,但不能在网站上读取。有没有办法在 iPhone 上保存视频的新方向,在发送到服务器之前?


//change Orientation Of video 

//in videoorientation.h 

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface videoorientationViewController : UIViewController
@property AVMutableComposition *mutableComposition;
@property AVMutableVideoComposition *mutableVideoComposition;
@property AVMutableAudioMix *mutableAudioMix;
@property AVAssetExportSession *exportSession;
- (void)performWithAsset : (NSURL *)moviename;
@end

In //viewcontroller.m 

- (void)performWithAsset : (NSURL *)moviename
{

    self.mutableComposition=nil;
    self.mutableVideoComposition=nil;
    self.mutableAudioMix=nil;

//    NSString* filename = [NSString stringWithFormat:@"temp1.mov"];
//    
//    NSLog(@"file name== %@",filename);
//    
//    [[NSUserDefaults standardUserDefaults]setObject:filename forKey:@"currentName"];
//    NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];

    // NSLog(@"file number %i",_currentFile);

    // NSURL* url = [NSURL fileURLWithPath:path];

    // NSString *videoURL = [[NSBundle mainBundle] pathForResource:@"Movie" ofType:@"m4v"];

    AVAsset *asset = [[AVURLAsset alloc] initWithURL:moviename options:nil];

    AVMutableVideoCompositionInstruction *instruction = nil;
    AVMutableVideoCompositionLayerInstruction *layerInstruction = nil;
    CGAffineTransform t1;
    CGAffineTransform t2;

    AVAssetTrack *assetVideoTrack = nil;
    AVAssetTrack *assetAudioTrack = nil;
    // Check if the asset contains video and audio tracks
    if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
        assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
    }
    if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
        assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
    }

    CMTime insertionPoint = kCMTimeZero;
    NSError *error = nil;


    // Step 1
    // Create a composition with the given asset and insert audio and video tracks into it from the asset
    if (!self.mutableComposition) {

        // Check whether a composition has already been created, i.e, some other tool has already been applied
        // Create a new composition
        self.mutableComposition = [AVMutableComposition composition];

        // Insert the video and audio tracks from AVAsset
        if (assetVideoTrack != nil) {
            AVMutableCompositionTrack *compositionVideoTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
            [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];
        }
        if (assetAudioTrack != nil) {
            AVMutableCompositionTrack *compositionAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
            [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];
        }

    }


    // Step 2
    // Translate the composition to compensate the movement caused by rotation (since rotation would cause it to move out of frame)
    t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0);
        float width=assetVideoTrack.naturalSize.width;
    float height=assetVideoTrack.naturalSize.height;
    float toDiagonal=sqrt(width*width+height*height);
    float toDiagonalAngle = radiansToDegrees(acosf(width/toDiagonal));
    float toDiagonalAngle2=90-radiansToDegrees(acosf(width/toDiagonal));

    float toDiagonalAngleComple;
    float toDiagonalAngleComple2;
    float finalHeight = 0.0;
    float finalWidth = 0.0;

    float degrees=90;

    if(degrees>=0&&degrees<=90){

        toDiagonalAngleComple=toDiagonalAngle+degrees;
        toDiagonalAngleComple2=toDiagonalAngle2+degrees;

        finalHeight=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple)));
        finalWidth=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple2)));

        t1 = CGAffineTransformMakeTranslation(height*sinf(degreesToRadians(degrees)), 0.0);
    }
    else if(degrees>90&&degrees<=180){


        float degrees2 = degrees-90;

        toDiagonalAngleComple=toDiagonalAngle+degrees2;
        toDiagonalAngleComple2=toDiagonalAngle2+degrees2;

        finalHeight=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple2)));
        finalWidth=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple)));

        t1 = CGAffineTransformMakeTranslation(width*sinf(degreesToRadians(degrees2))+height*cosf(degreesToRadians(degrees2)), height*sinf(degreesToRadians(degrees2)));
    }
    else if(degrees>=-90&&degrees<0){

        float degrees2 = degrees-90;
        float degreesabs = ABS(degrees);

        toDiagonalAngleComple=toDiagonalAngle+degrees2;
        toDiagonalAngleComple2=toDiagonalAngle2+degrees2;

        finalHeight=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple2)));
        finalWidth=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple)));

        t1 = CGAffineTransformMakeTranslation(0, width*sinf(degreesToRadians(degreesabs)));

    }
    else if(degrees>=-180&&degrees<-90){

        float degreesabs = ABS(degrees);
        float degreesplus = degreesabs-90;

        toDiagonalAngleComple=toDiagonalAngle+degrees;
        toDiagonalAngleComple2=toDiagonalAngle2+degrees;

        finalHeight=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple)));
        finalWidth=ABS(toDiagonal*sinf(degreesToRadians(toDiagonalAngleComple2)));

        t1 = CGAffineTransformMakeTranslation(width*sinf(degreesToRadians(degreesplus)), height*sinf(degreesToRadians(degreesplus))+width*cosf(degreesToRadians(degreesplus)));

    }


    // Rotate transformation
    t2 = CGAffineTransformRotate(t1, degreesToRadians(degrees));
    //t2 = CGAffineTransformRotate(t1, -90);


    // Step 3
    // Set the appropriate render sizes and rotational transforms
    if (!self.mutableVideoComposition) {

        // Create a new video composition
        self.mutableVideoComposition = [AVMutableVideoComposition videoComposition];
        // self.mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width);
        self.mutableVideoComposition.renderSize = CGSizeMake(finalWidth,finalHeight);

        self.mutableVideoComposition.frameDuration = CMTimeMake(1,30);

        // The rotate transform is set on a layer instruction
        instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [self.mutableComposition duration]);
        layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:(self.mutableComposition.tracks)[0]];
        [layerInstruction setTransform:t2 atTime:kCMTimeZero];

    } else {

        self.mutableVideoComposition.renderSize = CGSizeMake(self.mutableVideoComposition.renderSize.height, self.mutableVideoComposition.renderSize.width);

        // Extract the existing layer instruction on the mutableVideoComposition
        instruction = (self.mutableVideoComposition.instructions)[0];
        layerInstruction = (instruction.layerInstructions)[0];

        // Check if a transform already exists on this layer instruction, this is done to add the current transform on top of previous edits
        CGAffineTransform existingTransform;

        if (![layerInstruction getTransformRampForTime:[self.mutableComposition duration] startTransform:&existingTransform endTransform:NULL timeRange:NULL]) {
            [layerInstruction setTransform:t2 atTime:kCMTimeZero];
        } else {
            // Note: the point of origin for rotation is the upper left corner of the composition, t3 is to compensate for origin
            CGAffineTransform t3 = CGAffineTransformMakeTranslation(-1*assetVideoTrack.naturalSize.height/2, 0.0);
            CGAffineTransform newTransform = CGAffineTransformConcat(existingTransform, CGAffineTransformConcat(t2, t3));
            [layerInstruction setTransform:newTransform atTime:kCMTimeZero];
        }

    }


    // Step 4
    // Add the transform instructions to the video composition
    instruction.layerInstructions = @[layerInstruction];
    self.mutableVideoComposition.instructions = @[instruction];


    // Step 5
    // Notify AVSEViewController about rotation operation completion
    // [[NSNotificationCenter defaultCenter] postNotificationName:AVSEEditCommandCompletionNotification object:self];

    [self performWithAssetExport];
}

- (void)performWithAssetExport
{
    // Step 1
    // Create an outputURL to which the exported movie will be saved

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *outputURL = paths[0];
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil];
    outputURL = [outputURL stringByAppendingPathComponent:@"output.mov"];
    // Remove Existing File
    [manager removeItemAtPath:outputURL error:nil];


    // Step 2
    // Create an export session with the composition and write the exported movie to the photo library
    self.exportSession = [[AVAssetExportSession alloc] initWithAsset:[self.mutableComposition copy] presetName:AVAssetExportPreset1280x720];

    self.exportSession.videoComposition = self.mutableVideoComposition;
    self.exportSession.audioMix = self.mutableAudioMix;
    self.exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
    self.exportSession.outputFileType=AVFileTypeQuickTimeMovie;


    [self.exportSession exportAsynchronouslyWithCompletionHandler:^(void){
        switch (self.exportSession.status) {
            case AVAssetExportSessionStatusCompleted:

                //[self playfunction];

                [[NSNotificationCenter defaultCenter]postNotificationName:@"Backhome" object:nil];



                // Step 3
                // Notify AVSEViewController about export completion
                break;
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Failed:%@",self.exportSession.error);
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Canceled:%@",self.exportSession.error);
                break;
            default:
                break;
        }
    }];



}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改视频方向 的相关文章

  • Objective-c 中的块递归

    当执行涉及 Objective C 块的递归时 我在 iOS 应用程序中收到 EXC BAD ACCESS 信号 这是简化的代码 void problematicMethod FriendInfo friendInfo onComplete
  • 自定义 UITableViewCell 选择样式?

    当我点击我的UITableViewCell 当我单击单元格时 背景部分 我的背景图像未覆盖的区域 会变成蓝色 另外 所有的UILabel单击时单元格上的 s 变为白色 这就是我想要的 然而 我不想要的是当我点击它时的蓝色背景 但如果我这样做
  • 在iOS上,“添加到主页”缓存保存在哪里,如何清除它?

    我正在 iPad iOS v7 上制作一个 html5 游戏 当我将其添加到主页时 它非常顽固地释放缓存 如果我在 Safari 中查看它 这会按照您所期望的方式工作 如果我刷新一次或两次 页面就会以最新状态缓存 但在主页上却是另一回事 它
  • 错误域=AVFoundationErrorDomain代码=-11814“无法记录”

    它不断给我错误 错误域 AVFoundationErrorDomain代码 11814 无法记录 我不确定问题是什么 我试图在拍照后计数器达到 1 时录制声音 static int counter counter will always b
  • 如何在 iOS 中更改部分透明图像的颜色?

    我有一个具有部分透明度的单色图像 我有正常版本和 2X 版本的图像 我希望能够用代码将图像着色为不同的颜色 下面的代码适用于普通图像 但 2X 最终会出现伪影 正常图像可能有类似的问题如果是这样 由于分辨率的原因我无法检测到它 UIImag
  • 推入 UINavigationController 时隐藏 FBFriendPickerViewController 导航栏

    介绍一个实例FBFriendPickerViewController using presentViewController animated completion 非常简单 该类似乎是针对该用例的 但是 我想推送一个实例FBFriendP
  • iphone NSDate 转换问题

    在我的 facebook 图表 Api 中 我正在获取这些数据 来自杰森 updated time 2011 05 17T14 52 16 0000 我正在使用此代码将其转换为有效的日期格式 NSDateFormatter df NSDat
  • 个人帐户开发者之间的 Apple 开发/分发证书

    我一直在到处寻找有关处理证书的正确答案 想象一下以下帐户 Joe拥有个人 Apple 帐户 但他根本不会编码 他只是发布了该应用程序并将其称为自己的 Bob还有一个个人 Apple 帐户 Bob 是一位编码专家 Joe 付费让他开发他的第一
  • 我的游戏中应该有多少个视图控制器?

    我开始使用 spritekit 构建我的第一个游戏 现在我只有一个视图控制器来呈现开始屏幕场景 override func viewDidLoad super viewDidLoad let scene StartScreenScene C
  • 架构armv7的重复符号

    尝试在我现有的应用程序中使用 Layar SDK 时出现以下错误 我该如何解决这个问题 Ld Users pnawale Library Developer Xcode DerivedData hub afxxzaqisdfliwbzxbi
  • 使用 MFMailComposeViewController 类从 iPhone 应用程序发送带有 IMG 标签的 HTML 电子邮件

    我正在使用 MFMailComposeViewController 类从我的 iPhone 应用程序发送格式化的 HTML 电子邮件 我需要在电子邮件中包含图像 并且我在电子邮件正文中添加了 IMG 标签 IBAction shareWit
  • iphone:如何停止快门动画?

    我有两个问题 1 我想知道如何在相机加载时停止快门动画 我正在使用 UIImagePickerController 我已经参考了堆栈溢出的许多答案 但没有成功 2 我在相机中有一个自定义按钮 使用cameraOverlayView并想通过单
  • 在 UIImage 顶部绘制透明圆圈 - iPhone SDK

    我在尝试找出如何在 UIImageView 中的 UIImage 顶部绘制透明圆圈时遇到了很多麻烦 谷歌给了我线索 但我仍然找不到有效的例子 有没有人知道的例子可以证明这一点 最简单的方法就是创建一个半透明的方形 UIView 然后将其图层
  • 拖动时获取MKAnnotation的坐标

    我正在根据用户添加的注释的位置创建一条路径 MKPolyline 我想允许用户通过拖动引脚来更改路径 我目前可以做到这一点 但 MKPolyline 不会更新 直到引脚被放下 我实施了 void mapView MKMapView mapV
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的
  • Swift 中的 UIAlert 自动消失?

    我有以下代码 Creates Alerts on screen for user func notifyUser title String message String gt Void let alert UIAlertController
  • RemoteIO 音频单元播放回调中的 AudioBufferList 内容

    我想 拦截 音频数据传送到 iOS 设备扬声器的过程 我相信这可以使用 RemoteIO 音频单元和回调来完成 在下面的playbackCallback中 ioData实际上包含任何音频数据吗 static OSStatus playbac
  • CGImage/UIImage 在 UI 线程上延迟加载会导致卡顿

    我的程序显示一个水平滚动表面 从左到右平铺有 UIImageViews 代码在 UI 线程上运行 以确保新可见的 UIImageView 分配有新加载的 UIImage 加载发生在后台线程上 一切工作几乎都很好 除了每个图像变得可见时出现口
  • 为什么使用 iPhone 或 iOS 设备在“iframe”中查看“position:fixed”时不起作用?

    我研究过 stackoverflow 似乎position fixed在 iOS 移动设备的 iframe 中 https stackoverflow com questions 15874910 position fixed and if

随机推荐

  • 有没有办法创建一个可以接受数组和范围作为输入的 VBA 函数?

    我正在尝试创建一个函数 它可以接受范围或数组来执行一些进一步的计算 当数组通过时 该函数工作正常 但是当该函数在工作表中的范围内使用时 它会给我值 错误 我的代码如下所示 Function COMRET data as variant N
  • 反思:为什么会有setAccessible()这样的方法?

    只是想知道 为什么发明 Java 的人要写这样的方法setAccessible boolean flag 这使得访问修饰符 特别是私有的 无用并且无法保护字段 方法和构造函数不被访问 看下面的简单例子 public class BankAc
  • 如何在matplotlib中使颜色条一端的颜色变深?

    假设我有以下情节 import numpy as np import matplotlib pyplot as plt np random seed 1 data np sort np random rand 8 12 plt figure
  • Angular - 分派操作时出现“TypeError:无法冻结”

    我正在开发一个使用 ngrx 存储和效果的角度应用程序 我明白了 类型错误 无法冻结 从我的组件分派操作时出错 我写它是为了文件上传功能 我认为我正在改变状态 但不知道在哪里以及如何解决它 这是我的详细代码 Actions export e
  • ListView 在滚动底部加载更多内容

    在 MainActivity 中 我创建了 DownloadTask 它填充模型类 然后通过 CustomListAdapter 类填充列表视图 但我创建了函数来识别滚动结束 并且我想将更多项目加载到列表视图中 我正在互联网上阅读和查看代码
  • Bootstrap-Vue 和 Bootstrap 4 的比较

    我已经使用 Vuejs 来开发我的前端 现在我必须对其进行样式设置 我碰到Bootstrap vue https bootstrap vue js org docs 使用 Bootstrap 4 或 Bootstrap vue 哪个更好 它
  • 使用 AngularJS 在多个视图中显示相同的数据

    也许有人可以帮助我一点 我必须在多个视图之间共享数据 因为是学校项目 所以我必须使用AngularJS 但我对它很陌生 我不知道从哪里开始 该程序的工作原理如下 用户 顾客 可以在餐厅预订餐桌 第一页 用户 员工 可以将订单添加到保留的表中
  • 如何在Servlet 2.4版本的init()方法中获取ContextPath

    我使用的是2 4版本Servlet我需要得到ContextPath通过init 在服务器启动时调用的方法 所以我没有任何请求对象可以调用getContextPath 而且因为我没有Servlet版本getContextPath 方法中的Se
  • Ruby Net::SSH 使用变量插值更改目录

    我对 Ruby 还很陌生 所以如果我遗漏了一些明显的东西 请原谅我 问题是 Ruby 似乎没有在 Net SSH exec 中进行变量插值 方法 VCL DIR usr local etc varnish host 0 0 0 0 Net
  • jQuery:当在错误函数中使用时,getResponseHeader 在 IE 中不起作用

    我正在使用 jQuery 1 7 1 随着Ajax 表单插件 http jquery malsup com form 最新版本可用 当我执行 Ajax 请求时 例如 form ajaxForm success function data a
  • 使用手套中的训练数据获取数据集的词嵌入

    我最近在我的 mac 中安装了 gensim 和 glove 并尝试为我拥有的文本数据获取词嵌入 但是 我很难找到合适的功能 我只遇到过获取两个单词之间相似性度量的方法 如何使用库中存在的数据训练手套对象并使用它来获取数据集中单词的嵌入 或
  • 我应该如何在Python中使用random.jumpahead

    我有一个应用程序 可以将某个实验执行 1000 次 多线程 以便同时完成多个实验 每个实验都需要大约 50 000 次 random random 调用 获得真正随机的最佳方法是什么 我可以将随机对象复制到每个实验中 然后跳转 50 000
  • 网站可以检测到您何时将 selenium 与 geckodriver 一起使用吗?

    是否可以检测由 Selenium 和 geckodriver 控制的 Firefox 浏览器实例 注意有一个chromedriver 的相应答案 https stackoverflow com questions 33225947 can
  • 如何获取 Ant 中的 basedir 路径中最后一个文件夹的名称?

    假设我的 basedir c projects myapp 1 2 我怎样才能在房产中获得 1 2 Check this http ant apache org manual Tasks basename html out
  • Android 完全透明的状态栏?

    I ve searched the documentation but only found this Link http developer android com about versions android 4 4 html UI W
  • JavaScript 中的原型不好吗?

    In Felix 的 Node js 风格指南 http nodeguide com style html它说 不要扩展任何原型 对象 尤其是本地对象 那里 地狱里有一个特殊的地方等待着 如果你不遵守这条规则 本文 http howtono
  • 整数如何存储在内存中?

    当我阅读一篇有关大 小端的文章时 我很困惑 代码如下 include
  • 在 Centos 6.3 中使用 php-ldap

    我正在尝试使用 php 构建 LDAP 界面 但遇到了这个奇怪的问题 我已经在我的基本 php 安装上使用 yum 安装了 php ldap 包 但每当我调用 ldap connect 时 它都会说该函数未定义 看到 phpinfo 我可以
  • 正则表达式逗号后面没有空格

    我目前正在尝试创建一个表达式 以捕获所有后面没有空格的逗号以及所有冒号 我试过了 s 很接近 但似乎也抓住了逗号后面没有空格的字符 我也尝试过 s 它将抓取所有冒号和所有逗号 其后有一个空格以及空格 我希望选择的内容包含在下面的 中 你好
  • 如何更改视频方向

    我目前有一个 iPhone 应用程序 可以让用户拍摄视频 将其上传到服务器 并允许其他人从该应用程序查看他们的视频 从来没有遇到过视频方向的问题 直到我制作一个网站来观看不同的视频 以及其他内容 我使用来自网络服务的视频 并使用 video