【发布时间】:2014-01-06 10:39:51
【问题描述】:
我正在开发一个编辑视频的应用。录制视频时没有问题,因为最初我会设置所有设置,如饱和度、亮度、对比度等。
但问题在于录制的视频。我无法更改已录制视频的上述所有属性。
任何人请告诉我他的问题的解决方案。
任何好的解决方案,建议将不胜感激。
【问题讨论】:
-
我也有同样的问题。
标签: ios video avfoundation core-video
我正在开发一个编辑视频的应用。录制视频时没有问题,因为最初我会设置所有设置,如饱和度、亮度、对比度等。
但问题在于录制的视频。我无法更改已录制视频的上述所有属性。
任何人请告诉我他的问题的解决方案。
任何好的解决方案,建议将不胜感激。
【问题讨论】:
标签: ios video avfoundation core-video
电影可以通过 GPUImageMovie 类加载到框架中,过滤,然后使用 GPUImageMovieWriter 写出。 GPUImageMovieWriter 的速度也足够快,可以从 iPhone 4 的摄像头实时录制 640x480 的视频,因此可以将直接过滤的视频源输入其中。
以下示例说明了如何加载示例影片,将其通过像素化和旋转过滤器,然后将结果作为 480 x 640 h.264 影片记录到磁盘:
movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
pixellateFilter = [[GPUImagePixellateFilter alloc] init];
GPUImageRotationFilter *rotationFilter = [[GPUImageRotationFilter alloc] initWithRotation:kGPUImageRotateRight];
[movieFile addTarget:rotationFilter];
[rotationFilter addTarget:pixellateFilter];
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
[pixellateFilter addTarget:movieWriter];
[movieWriter startRecording];
[movieFile startProcessing];
录制完成后,您需要从过滤器链中删除电影录制器并使用如下代码关闭录制:
[pixellateFilter removeTarget:movieWriter];
[movieWriter finishRecording];
电影在完成之前无法使用,因此如果在此之前中断,录制将会丢失。
这里有很好的教程:
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
请参阅“过滤和重新编码电影”部分。
【讨论】:
这是对我有用的代码。我使用了GPUImage。
viewController.h
#import "GPUImage.h"
GPUImageMovie *movieFile;
GPUImageOutput<GPUImageInput> *filter;
GPUImageMovieWriter *movieWriter;
int ArrayIndex;
UISlider *mSlider;
ViewController.m
NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"sample_iPod" withExtension:@"m4v"];
mSlider=[[UISlider alloc]initWithFrame:CGRectMake(60,380,200, 30)];
mSlider.continuous=YES;
[mSlider addTarget:self action:@selector(updatePixelWidth:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mSlider];
movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = YES;
if(ArrayIndex==0)
{
filter=[[GPUImageBrightnessFilter alloc]init];
mSlider.maximumValue=1.0;
mSlider.minimumValue=-1.0;
mSlider.value=0.0;
}
else if(ArrayIndex==1)
{
filter=[[GPUImageContrastFilter alloc]init];
mSlider.minimumValue=0.0;
mSlider.maximumValue=4.0;
mSlider.value=1.0;
}
else if(ArrayIndex==2)
{
filter=[[GPUImageSaturationFilter alloc]init];
mSlider.minimumValue=0.0;
mSlider.maximumValue=2.0;
mSlider.value=1.0;
}
[movieFile addTarget:filter];
// Only rotate the video for display, leave orientation the same for recording
GPUImageView *filterView = (GPUImageView *)self.view;
[filter addTarget:filterView];
// In addition to displaying to the screen, write out a processed version of the movie to disk
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)];
[filter addTarget:movieWriter];
// Configure this for video from the movie file, where we want to preserve all video frames and audio samples
movieWriter.shouldPassthroughAudio = YES;
movieFile.audioEncodingTarget = movieWriter;
[movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
[movieWriter startRecording];
[movieFile startProcessing];
[movieWriter setCompletionBlock:^{
[filter removeTarget:movieWriter];
[movieWriter finishRecording];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (pathToMovie)) {
UISaveVideoAtPathToSavedPhotosAlbum (pathToMovie,self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}];
- (void)updatePixelWidth:(id)sender
{
if(ArrayIndex==0)
{
[(GPUImageBrightnessFilter *)filter setBrightness:[(UISlider *)sender value]];
}
else if (ArrayIndex==1)
{
[(GPUImageContrastFilter *)filter setContrast:[(UISlider *)sender value]];
}
else if (ArrayIndex==2)
{
[(GPUImageSaturationFilter *)filter setSaturation:[(UISlider *)sender value]];
}
}
【讨论】: