iOS图片,视频上传&视频内容旋转

#前言
我最近在接手一个智能盒子的iOS应用,上面有一个功能是这样的。把你本地的照片和视频能够甩屏到你绑定的盒子上。
个人上一位前辈作的时候必需要求再同一个局域网,可是当我作的时候要求不一样的局域网也要实现这样的一个功能,优化用户的使用感觉。javascript


#那么 咱们下面就进入正题。java

#内容一:图片上传
我作的图片上传是用的AF,原理就是把你想上传的照片取出来,若是有文件大小的要求就先作相应的图片压缩。
而后用AFHTTPSessionManager 类去作的上传,下面就是代码:session

AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
    [session.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    session.requestSerializer.timeoutInterval = 60.f;
    [session.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    session.responseSerializer = [AFHTTPResponseSerializer serializer];

    NSString *imageTitle =_imageSource[pageIndex].title;
    imageTitle = [imageTitle substringToIndex:imageTitle.length-4];


    NSDictionary *params = @{
                          @"fileType":@"jpg",
                          @"fileName":imageTitle
                          };
    [session POST:@"你上传的接口地址" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (NSString *key in dict.allKeys) {
            [formData appendPartWithFileData:[dict objectForKey:key] name:@"myFile" fileName:[NSString stringWithFormat:@"%@.jpg",key] mimeType:@"image/jpeg"];
        }

    } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    }];复制代码

这里主要就是和大家的后台确认好相应的参数设置就行了。app


#内容二:视频上传
视频上传和图片上传实际上是相似的,只不过就是参数的设置不同而已。也是用上面的方法。关键也是设置好参数。
在这里我想说的是,有的时候视频太大要作相应的压缩处理。由于我以前对视频这面接触的比较少,也上网找了一些资料而后看到这样的一个方法:ide

- (void)lowQuailtyWithInputURL:(NSURL*)inputURL
                      outputURL:(NSURL*)outputURL
                   blockHandler:(void (^)(AVAssetExportSession*))handler
{
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset     presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = outputURL;
    session.outputFileType = AVFileTypeQuickTimeMovie;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
     {
        handler(session);
     }];
}复制代码

经过这个方法就能够对视频进行相应的压缩处理。优化


#下面就是视频内容的旋转问题了。
一开始我听到了这个需求的时候个人脑子里真的是瞬间万马飞奔啊!! 这是什么鬼需求啊!鬼知道我经历了什么?
我想,那我就上网找一下吧!我找了一下,还真的有这么样的技术博客。可是一上来就是把他的代码网上一贴。我先大概的浏览了一下那代码的长度。写的我实在是没有耐心去仔细的看究竟是怎么实现的。我就关掉了。但是后来一看,也没有别的什么博客供我参考了。在我走投无路的时候,我看到了这么一个博客,说是Apple本身就有Demo,我就抱着好奇的态度去看了看。下载了那个Demo仔细的研究了一下。果真就好使了。 那么,接下来就说一下。ui

再旋转视频以前咱们先要确认一下,这个视频是要旋转多少度。this

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    NSInteger degress;
    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;
        }
    }复制代码

这样咱们就能够经过degress来确认旋转的角度了。
那么咱们接下来就开始旋转视频spa

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 (!mutableComposition) {
        // Check whether a composition has already been created, i.e, some other tool has already been applied
        // Create a new composition
        mutableComposition = [AVMutableComposition composition];
        // Insert the video and audio tracks from AVAsset
        if (assetVideoTrack != nil) {
            AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
            [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];
        }
        if (assetAudioTrack != nil) {
            AVMutableCompositionTrack *compositionAudioTrack = [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);
// // Rotate transformation
// t2 = CGAffineTransformRotate(t1, degreesToRadians(90));
    if (degress == 0) {
        t1 = CGAffineTransformMakeTranslation(0.0, 0.0);
        t2 = CGAffineTransformRotate(t1, degreesToRadians(0));
    }else if (degress == 90){
        t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0);
        t2 = CGAffineTransformRotate(t1, degreesToRadians(90));
    }else if (degress == 180){
        t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.width, assetVideoTrack.naturalSize.height);
        t2 = CGAffineTransformRotate(t1, degreesToRadians(180));
    }else if (degress == 270){
        t1 = CGAffineTransformMakeTranslation(0,assetVideoTrack.naturalSize.height*1.78);
        t2 = CGAffineTransformRotate(t1, degreesToRadians(-90));
    }
    // Step 3
    // Set the appropriate render sizes and rotational transforms
    if (!mutableVideoComposition) {
        // Create a new video composition
        mutableVideoComposition = [AVMutableVideoComposition videoComposition];
        if (degress == 0 || degress == 180) {
            mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.width,assetVideoTrack.naturalSize.height);
        }else{
            mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width);
        }
        mutableVideoComposition.frameDuration = CMTimeMake(1, 30);
        // The rotate transform is set on a layer instruction
        instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mutableComposition duration]);
        layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:(mutableComposition.tracks)[0]];
        [layerInstruction setTransform:t2 atTime:kCMTimeZero];
    } else {
        mutableVideoComposition.renderSize = CGSizeMake(mutableVideoComposition.renderSize.height, mutableVideoComposition.renderSize.width);
        // Extract the existing layer instruction on the mutableVideoComposition
        instruction = (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:[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];
    mutableVideoComposition.instructions = @[instruction];复制代码

到这个时候呢视频的旋转已经完成了。
上面咱们不是写了一个视频压缩的方法吗?把这个时候生成的mutableVideoComposition赋值给session.videoComposition = mutableVideoComposition;就行了。这样就是先旋转视频而后直接压缩完成咱们的需求。code

相关文章
相关标签/搜索