【问题标题】:Video recorded from EAGLView is flipped when uploaded to youtube从 EAGLView 录制的视频在上传到 youtube 时会翻转
【发布时间】:2013-09-23 04:48:50
【问题描述】:

在我的 ios 应用程序中,我正在尝试录制 EAGLView 内容的视频(没有相机参与)。我录制视频没有问题。 录制后,我必须在视频中添加一些音轨,然后必须将此视频分享到 Youtube 和 Facebook。我的问题是,当我在 iphone 或 mac 上播放视频时,视频还可以,但是当我将此视频上传到 youtube(使用 Youtube Data Api v3)时,视频是垂直倒置或倒置的。

我想我需要在上传之前旋转视频中的帧,但我不知道该怎么做。

我们将不胜感激。

我用来为视频添加音轨的代码如下:

-(void)prepareVideoForPath:(NSString *)videoPath usingAudio:(NSArray *)audioArray andOutputPath:(NSString *)exportPath{


NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

NSURL *videoUrl=[NSURL fileURLWithPath:videoPath];

AVURLAsset* videoAsset = [AVURLAsset URLAssetWithURL:videoUrl options:optionsDictionary];

AVAssetTrack *FirstAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGAffineTransform firstTransform = FirstAssetTrack.preferredTransform;
AVMutableComposition* mixComposition = [AVMutableComposition composition];


//VideoTrack

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:FirstAssetTrack atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:firstTransform];


//Audio Track

AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

CMTime audioStartTime = kCMTimeZero;
for (NSURL *audioURL in audioArray) {
    AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:audioURL options:optionsDictionary];
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:audioStartTime error:nil];
    audioStartTime = CMTimeAdd(audioStartTime, audioAsset.duration);
}


AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough];


NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];

_assetExport.outputFileType = AVFileTypeQuickTimeMovie;

NSLog(@"file type %@",_assetExport.outputFileType);

_assetExport.outputURL = exportUrl;

_assetExport.shouldOptimizeForNetworkUse = YES;

[_assetExport exportAsynchronouslyWithCompletionHandler:

 ^(void ) {

     // your completion code here

     dispatch_async(dispatch_get_main_queue(), ^{
         NSLog(@"Mixing complete");

     });

 }

 ];

}

【问题讨论】:

  • 我想知道您如何录制 GLKView 中显示的内容的视频。通过搜索论坛,我知道我是否可以获得一系列图像,我可以将它们渲染成视频。您是否先获取图像并将其渲染成视频?如果是这样,您如何获取图像?您是否定期或以其他方式捕获屏幕?你能给我一些线索吗?谢谢!
  • 您可以通过使用 glReadPixels() 创建一系列图像来创建视频,但使用起来非常昂贵。另一种方法是使用非常快速和高效的帧缓冲区对象(FBO)。我成功地使用 FBO 创建了视频,但弄乱了屏幕上的内容显示,即屏幕上没有显示任何内容,一切都将成为视频。我对openGLES不太满意。我目前正在使用Everyplay SDK 录制我的 GLKView 的视频。
  • 感谢您的回复。我会试试 Everyplay SDK。

标签: iphone ios opengl-es-2.0 avmutablecomposition google-api-objc-client


【解决方案1】:

好的,我找到了如何旋转视频。

代码如下:

-(void)fixVideoOrientationForURL:(NSURL *)videoURL andOutputPath:(NSString *)exportPath{


    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoURL options:@{ AVURLAssetPreferPreciseDurationAndTimingKey:@YES }];

    AVMutableVideoCompositionInstruction *instruction = nil;
    AVMutableVideoCompositionLayerInstruction *layerInstruction = nil;

    CGAffineTransform transform;

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

AVMutableComposition *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)
// Rotate transformation
    transform = CGAffineTransformMake(1, 0, 0, -1, 0, assetVideoTrack.naturalSize.height);

// Step 3
// Set the appropriate render sizes and rotational transforms


    // Create a new video composition
    AVMutableVideoComposition *mutableVideoComposition = [AVMutableVideoComposition videoComposition];
    mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.width,assetVideoTrack.naturalSize.height);
    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];

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


    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[mutableComposition copy] presetName:AVAssetExportPresetHighestQuality];

exportSession.videoComposition = mutableVideoComposition;
exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputFileType=AVFileTypeQuickTimeMovie;
exportSession.shouldOptimizeForNetworkUse = YES;

[exportSession exportAsynchronouslyWithCompletionHandler:^(void){

        dispatch_async(dispatch_get_main_queue(), ^{
            switch (exportSession.status) {
                case AVAssetExportSessionStatusCompleted:
                    NSLog(@"writing complete");


                    break;
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"Failed:%@",exportSession.error);
                    break;
                case AVAssetExportSessionStatusCancelled:
                    NSLog(@"Canceled:%@",exportSession.error);
                    break;
                default:
                    break;
            }
        });

}];
}

【讨论】:

    猜你喜欢
    • 2017-06-19
    • 2012-12-25
    • 2017-04-13
    • 2011-11-30
    • 2020-05-12
    • 1970-01-01
    • 2015-02-01
    • 2013-05-29
    • 2012-09-16
    相关资源
    最近更新 更多