{"action":"created","issue":{"url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/250","repository_url":"https://api.github.com/repos/banchichen/TZImagePickerController","labels_url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/250/labels{/name}","comments_url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/250/comments","events_url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/250/events","html_url":"https://github.com/banchichen/TZImagePickerController/issues/250","id":182228524,"number":250,"title":"iOS平台相册视频方向问题","user":{"login":"zywang","id":680810,"avatar_url":"https://avatars.githubusercontent.com/u/680810?v=3","gravatar_id":"","url":"https://api.github.com/users/zywang","html_url":"https://github.com/zywang","followers_url":"https://api.github.com/users/zywang/followers","following_url":"https://api.github.com/users/zywang/following{/other_user}","gists_url":"https://api.github.com/users/zywang/gists{/gist_id}","starred_url":"https://api.github.com/users/zywang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zywang/subscriptions","organizations_url":"https://api.github.com/users/zywang/orgs","repos_url":"https://api.github.com/users/zywang/repos","events_url":"https://api.github.com/users/zywang/events{/privacy}","received_events_url":"https://api.github.com/users/zywang/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-10-11T10:25:41Z","updated_at":"2016-10-18T08:25:29Z","closed_at":null,"body":"今天使用中发现，从相册选取一个竖屏方向的视频，使用第三方播放器播放（IJKPlayer），视频会变成横屏。\r\n原因是iOS的平台的图片和视频有个方向信息，我看现有库对图片做方向纠正的处理，视频还没有处理，我临时扩展一下到处视频函数，解决了这个问题，供大家遇到类似问题参考。\r\n\r\n希望作者看到，能加入这个逻辑。\r\n\r\n/// Export Video / 导出视频\r\n- (void)getVideoOutputPathWithAssetForMX:(id)asset completion:(void (^)(NSString *outputPath))completion {\r\n    if ([asset isKindOfClass:[PHAsset class]]) {\r\n        PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];\r\n        options.version = PHVideoRequestOptionsVersionOriginal;\r\n        options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;\r\n        options.networkAccessAllowed = YES;\r\n        [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){\r\n            // NSLog(@\"Info:\\n%@\",info);\r\n            AVURLAsset *videoAsset = (AVURLAsset*)avasset;\r\n            // NSLog(@\"AVAsset URL: %@\",myAsset.URL);\r\n            //            [self startExportVideoWithVideoAsset:videoAsset completion:completion];\r\n            \r\n            // 扩展调整视频方向接口\r\n            int degress = [self degressFromVideoFileWithAssetForMX:avasset];\r\n            [self startExportVideoWithVideoAssetForMX:videoAsset degrees:degress completion:completion];\r\n        }];\r\n#pragma clang diagnostic push\r\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\r\n    } else if ([asset isKindOfClass:[ALAsset class]]) {\r\n        NSURL *videoURL =[asset valueForProperty:ALAssetPropertyAssetURL]; // ALAssetPropertyURLs\r\n#pragma clang diagnostic pop\r\n        AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:videoURL options:nil];\r\n        [self startExportVideoWithVideoAssetForMX:videoAsset completion:completion];\r\n    }\r\n}\r\n\r\n- (void)startExportVideoWithVideoAssetForMX:(AVURLAsset *)videoAsset degrees:(int)degrees completion:(void (^)(NSString *outputPath))completion {\r\n    // Find compatible presets by video asset.\r\n    NSArray *presets = [AVAssetExportSession exportPresetsCompatibleWithAsset:videoAsset];\r\n    \r\n    // Begin to compress video\r\n    // Now we just compress to low resolution if it supports\r\n    // If you need to upload to the server, but server does't support to upload by streaming,\r\n    // You can compress the resolution to lower. Or you can support more higher resolution.\r\n    if ([presets containsObject:AVAssetExportPreset640x480]) {\r\n        AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:videoAsset presetName:AVAssetExportPreset640x480];\r\n        \r\n        NSDateFormatter *formater = [[NSDateFormatter alloc] init];\r\n        [formater setDateFormat:@\"yyyy-MM-dd-HH:mm:ss\"];\r\n        NSString *outputPath = [NSHomeDirectory() stringByAppendingFormat:@\"/tmp/output-%@.mp4\", [formater stringFromDate:[NSDate date]]];\r\n        NSLog(@\"video outputPath = %@\",outputPath);\r\n        session.outputURL = [NSURL fileURLWithPath:outputPath];\r\n        \r\n        // Optimize for network use.\r\n        session.shouldOptimizeForNetworkUse = true;\r\n        \r\n        NSArray *supportedTypeArray = session.supportedFileTypes;\r\n        if ([supportedTypeArray containsObject:AVFileTypeMPEG4]) {\r\n            session.outputFileType = AVFileTypeMPEG4;\r\n        } else if (supportedTypeArray.count == 0) {\r\n            NSLog(@\"No supported file types 视频类型暂不支持导出\");\r\n            return;\r\n        } else {\r\n            session.outputFileType = [supportedTypeArray objectAtIndex:0];\r\n        }\r\n        \r\n        if (![[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingFormat:@\"/tmp\"]]) {\r\n            [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingFormat:@\"/tmp\"] withIntermediateDirectories:YES attributes:nil error:nil];\r\n        }\r\n        \r\n        if (degrees != 0) {\r\n            CGAffineTransform translateToCenter;\r\n            CGAffineTransform mixedTransform;\r\n            AVMutableVideoComposition *waterMarkVideoComposition = [AVMutableVideoComposition videoComposition];\r\n            waterMarkVideoComposition.frameDuration = CMTimeMake(1, 30);\r\n            \r\n            NSArray *tracks = [videoAsset tracksWithMediaType:AVMediaTypeVideo];\r\n            AVAssetTrack *videoTrack = [tracks objectAtIndex:0];\r\n            \r\n            if (degrees == 90) {\r\n                // 顺时针旋转90°\r\n                translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, 0.0);\r\n                mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2);\r\n                waterMarkVideoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);\r\n            } else if(degrees == 180){\r\n                // 顺时针旋转180°\r\n                translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.width, videoTrack.naturalSize.height);\r\n                mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI);\r\n                waterMarkVideoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.width,videoTrack.naturalSize.height);\r\n            } else if(degrees == 270){\r\n                // 顺时针旋转270°\r\n                translateToCenter = CGAffineTransformMakeTranslation(0.0, videoTrack.naturalSize.width);\r\n                mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2*3.0);\r\n                waterMarkVideoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);\r\n            }\r\n            \r\n            AVMutableVideoCompositionInstruction *roateInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];\r\n            roateInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);\r\n            AVMutableVideoCompositionLayerInstruction *roateLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];\r\n            \r\n            [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];\r\n            \r\n            roateInstruction.layerInstructions = @[roateLayerInstruction];\r\n            //将视频方向旋转加入到视频处理中\r\n            waterMarkVideoComposition.instructions = @[roateInstruction];\r\n            \r\n            session.videoComposition = waterMarkVideoComposition;\r\n        }\r\n        \r\n        // Begin to export video to the output path asynchronously.\r\n        [session exportAsynchronouslyWithCompletionHandler:^(void) {\r\n            switch (session.status) {\r\n                case AVAssetExportSessionStatusUnknown:\r\n                    NSLog(@\"AVAssetExportSessionStatusUnknown\"); break;\r\n                case AVAssetExportSessionStatusWaiting:\r\n                    NSLog(@\"AVAssetExportSessionStatusWaiting\"); break;\r\n                case AVAssetExportSessionStatusExporting:\r\n                    NSLog(@\"AVAssetExportSessionStatusExporting\"); break;\r\n                case AVAssetExportSessionStatusCompleted: {\r\n                    NSLog(@\"AVAssetExportSessionStatusCompleted\");\r\n                    dispatch_async(dispatch_get_main_queue(), ^{\r\n                        if (completion) {\r\n                            completion(outputPath);\r\n                        }\r\n                    });\r\n                }  break;\r\n                case AVAssetExportSessionStatusFailed:\r\n                    NSLog(@\"AVAssetExportSessionStatusFailed\"); break;\r\n                default: break;\r\n            }\r\n        }];\r\n    }\r\n}\r\n\r\n//获取视频角度\r\n- (int)degressFromVideoFileWithAssetForMX:(AVAsset *)asset {\r\n    int degress = 0;\r\n    \r\n    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];\r\n    if([tracks count] > 0) {\r\n        AVAssetTrack *videoTrack = [tracks objectAtIndex:0];\r\n        CGAffineTransform t = videoTrack.preferredTransform;\r\n        \r\n        if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0){\r\n            // Portrait\r\n            degress = 90;\r\n        }else if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0){\r\n            // PortraitUpsideDown\r\n            degress = 270;\r\n        }else if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0){\r\n            // LandscapeRight\r\n            degress = 0;\r\n        }else if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0){\r\n            // LandscapeLeft\r\n            degress = 180;\r\n        }\r\n    }\r\n    \r\n    return degress;\r\n}\r\n"},"comment":{"url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/comments/254440542","html_url":"https://github.com/banchichen/TZImagePickerController/issues/250#issuecomment-254440542","issue_url":"https://api.github.com/repos/banchichen/TZImagePickerController/issues/250","id":254440542,"user":{"login":"zywang","id":680810,"avatar_url":"https://avatars.githubusercontent.com/u/680810?v=3","gravatar_id":"","url":"https://api.github.com/users/zywang","html_url":"https://github.com/zywang","followers_url":"https://api.github.com/users/zywang/followers","following_url":"https://api.github.com/users/zywang/following{/other_user}","gists_url":"https://api.github.com/users/zywang/gists{/gist_id}","starred_url":"https://api.github.com/users/zywang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zywang/subscriptions","organizations_url":"https://api.github.com/users/zywang/orgs","repos_url":"https://api.github.com/users/zywang/repos","events_url":"https://api.github.com/users/zywang/events{/privacy}","received_events_url":"https://api.github.com/users/zywang/received_events","type":"User","site_admin":false},"created_at":"2016-10-18T08:25:29Z","updated_at":"2016-10-18T08:25:29Z","body":"赞！"}}
{"actor":{"display_login":"zywang"}}