iOS视频合成(图⽚和视频的合成,视频跟⾳频的合成)
这个给我的感觉就像是PPT播放⼀样。这⾥找了⼀些资料,学习视频合成⽅⾯的知识。
⼀:图⽚和视频的合成:
@interfaceViewController()
@property(nonatomic,strong)NSMutableArray*imageArr;
@property(nonatomic,strong)NSString*theVideoPath;
@end
@implementationViewController
-(void)viewDidLoad{
[superviewDidLoad];
rr=[[NSMutableArrayalloc]initWithObjects:
[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@"7"],[UIImageimageNamed:@"8"],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],[UIImageimageNamed:@""],[UIImage
imageNamed:@""],[UIImageimageNamed:@""],nil];
UIButton*button=[UIButtonbuttonWithType:UIButtonTypeRoundedRect];
[buttontFrame:CGRectMake(100,100,100,100)];
[buttontTitle:@"合成"forState:UIControlStateNormal];
[buttonaddTarget:lf
action:@lector(testCompressionSession)forControlEvents:UIControlEventTouchUpInside];
[dSubview:button];
UIButton*button1=[UIButtonbuttonWithType:UIButtonTypeRoundedRect];
[button1tFrame:CGRectMake(100,200,100,100)];
[button1tTitle:@"播放"forState:UIControlStateNormal];
[button1addTarget:lfaction:@lector(playAction)forControlEvents:UIControlEventTouchUpInside];
[dSubview:button1];
//Doanyadditionaltupafterloadingtheview,typicallyfromanib.
}
-(void)testCompressionSession
{
NSLog(@"开始");
//NSString*moviePath=[[NSBundlemainBundle]pathForResource:@"Movie"ofType:@"mov"];
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUrDomainMask,YES);
NSString*moviePath=[[pathsobjectAtIndex:0]stringByAppendingPathComponent:[NSString
stringWithFormat:@"%@.mp4",@"2016全球三⼤超跑宣传⽚_超清"]];
eoPath=moviePath;
CGSizesize=CGSizeMake(320,400);//定义视频的⼤⼩
//[lfwriteImages:_imageArrToMovieAtPath:moviePathwithSize:sizeinDuration:4byFPS:30];//第2中⽅法
NSError*error=nil;
unlink([moviePathUTF8String]);
NSLog(@"path->%@",moviePath);
//—-initializecompressionengine
AVAstWriter*videoWriter=[[AVAstWriteralloc]initWithURL:[NSURL
fileURLWithPath:moviePath]fileType:AVFileTypeQuickTimeMovieerror:&error];
NSParameterAsrt(videoWriter);
if(error)
NSLog(@"error=%@",[errorlocalizedDescription]);
NSDictionary*videoSettings=[NSDictionary
dictionaryWithObjectsAndKeys:AVVideoCodecH264,AVVideoCodecKey,
[NSNumbernumberWithInt:],AVVideoWidthKey,
[NSNumbernumberWithInt:],AVVideoHeightKey,nil];
AVAstWriterInput*writerInput=[AVAstWriterInputastWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
NSDictionary*sourcePixelBufferAttributesDictionary=[NSDictionarydictionaryWithObjectsAndKeys:
[NSNumbernumberWithInt:kCVPixelFormatType_32ARGB],kCVPixelBufferPixelFormatTypeKey,nil];
AVAstWriterInputPixelBufferAdaptor*adaptor=[AVAstWriterInputPixelBufferAdaptor
astWriterInputPixelBufferAdaptorWithAstWriterInput:writerInput
sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
NSParameterAsrt(writerInput);
NSParameterAsrt([videoWritercanAddInput:writerInput]);
if([videoWritercanAddInput:writerInput])
NSLog(@"11111");
el
NSLog(@"22222");
[videoWriteraddInput:writerInput];
[videoWriterstartWriting];
[videoWriterstartSessionAtSourceTime:kCMTimeZero];
//合成多张图⽚为⼀个视频⽂件
dispatch_queue_tdispatchQueue=dispatch_queue_create("mediaInputQueue",NULL);
int__blockframe=0;
[writerInputrequestMediaDataWhenReadyOnQueue:dispatchQueueusingBlock:^{
while([writerInputisReadyForMoreMediaData])
{
if(++frame>=[rrcount]*10)
{
[writerInputmarkAsFinished];
[videoWriterfinishWriting];
break;}
CVPixelBufferRefbuffer=NULL;
intidx=frame/10;
NSLog(@"idx==%d",idx);
buffer=(CVPixelBufferRef)
[lfpixelBufferFromCGImage:[[rrobjectAtIndex:idx]CGImage]size:size];
if(buffer){
if(![adaptorappendPixelBuffer:bufferwithPrentationTime:CMTimeMake(frame,10)])
NSLog(@"FAIL");
el
NSLog(@"OK");
CFRelea(buffer);}}}];}
-(CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)imagesize:(CGSize)size{
NSDictionary*options=[NSDictionarydictionaryWithObjectsAndKeys:
[NSNumbernumberWithBool:YES],kCVPixelBufferCGImageCompatibilityKey,
[NSNumbernumberWithBool:YES],kCVPixelBufferCGBitmapContextCompatibilityKey,nil];
CVPixelBufferRefpxbuffer=NULL;
CVReturnstatus
=CVPixelBufferCreate(kCFAllocatorDefault,,,kCVPixelFormatType_32ARGB,(__bridge
CFDictionaryRef)options,&pxbuffer);
NSParameterAsrt(status==kCVReturnSuccess&&pxbuffer!=NULL);
CVPixelBufferLockBaAddress(pxbuffer,0);
void*pxdata=CVPixelBufferGetBaAddress(pxbuffer);
NSParameterAsrt(pxdata!=NULL);
CGColorSpaceRefrgbColorSpace=CGColorSpaceCreateDeviceRGB();
CGContextRefcontext
=CGBitmapContextCreate(pxdata,,,8,4*,rgbColorSpace,kCGImageAlphaPremul
tipliedFirst);
NSParameterAsrt(context);
CGContextDrawImage(context,CGRectMake(0,0,CGImageGetWidth(image),CGImageGetHeight(image)),
image);
CGColorSpaceRelea(rgbColorSpace);
CGContextRelea(context);
CVPixelBufferUnlockBaAddress(pxbuffer,0);
returnpxbuffer;}
-(void)playAction{
MPMoviePlayerViewController*theMovie=[[MPMoviePlayerViewControlleralloc]initWithContentURL:
[NSURLfileURLWithPath:eoPath]];
[lfprentMoviePlayerViewControllerAnimated:theMovie];
ourceType=MPMovieSourceTypeFile;[layerplay];}
//第⼆种⽅式
-(void)writeImages:(NSArray*)imagesArrayToMovieAtPath:(NSString*)pathwithSize:(CGSize)size
inDuration:(float)durationbyFPS:(int32_t)fps{
//Wirethewriter:
NSError*error=nil;
AVAstWriter*videoWriter=[[AVAstWriteralloc]initWithURL:[NSURL
fileURLWithPath:path]fileType:AVFileTypeQuickTimeMovieerror:&error];
NSParameterAsrt(videoWriter);
NSDictionary*videoSettings=[NSDictionarydictionaryWithObjectsAndKeys:
AVVideoCodecH264,AVVideoCodecKey,
[NSNumbernumberWithInt:],AVVideoWidthKey,
[NSNumbernumberWithInt:],AVVideoHeightKey,nil];
AVAstWriterInput*videoWriterInput=[AVAstWriterInput
astWriterInputWithMediaType:AVMediaTypeVideooutputSettings:videoSettings];
AVAstWriterInputPixelBufferAdaptor*adaptor=
[AVAstWriterInputPixelBufferAdaptorastWriterInputPixelBufferAdaptorWithAstWriterInput:videoWri
terInputsourcePixelBufferAttributes:nil];
NSParameterAsrt(videoWriterInput);
NSParameterAsrt([videoWritercanAddInput:videoWriterInput]);
[videoWriteraddInput:videoWriterInput];
//Startassion:
[videoWriterstartWriting];
[videoWriterstartSessionAtSourceTime:kCMTimeZero];
//Writesomesamples:
CVPixelBufferRefbuffer=NULL;
intframeCount=0;
intimagesCount=[imagesArraycount];
floataverageTime=duration/imagesCount;
intaverageFrame=(int)(averageTime*fps);
for(UIImage*imginimagesArray){
buffer=[lfpixelBufferFromCGImage:[imgCGImage]size:size];
BOOLappend_ok=NO;
intj=0;
while(!append_ok&&j<=30)
{
if(orMoreMediaData)
{
printf("appending%dattemp%dn",frameCount,j);
CMTimeframeTime=CMTimeMake(frameCount,(int32_t)fps);floatframeSeconds
=CMTimeGetSeconds(frameTime);
NSLog(@"frameCount:%d,kRecordingFPS:%d,frameSeconds:%f",frameCount,fps,frameSeconds);
append_ok=[adaptorappendPixelBuffer:bufferwithPrentationTime:frameTime];
if(buffer)
[NSThreadsleepForTimeInterval:0.05];}el{
printf("adaptornotready%d,%dn",frameCount,j);
[NSThreadsleepForTimeInterval:0.1];}
j++;}
if(!append_ok){
printf("errorappendingimage%dtimes%dn",frameCount,j);}
frameCount=frameCount+averageFrame;}
//Finishthession:
[videoWriterInputmarkAsFinished];
[videoWriterfinishWriting];NSLog(@"finishWriting");}
⼆:视频跟⾳频的合成
//混合⾳乐
-(void)merge{
//mbp提⽰框
//[MBProgressHUDshowMessage:@"正在处理中"];
//路径
NSString*documents=[NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];
//声⾳来源
NSURL*audioInputUrl=[NSURLfileURLWithPath:[[NSBundlemainBundle]pathForResource:@"蓝瘦⾹菇"
ofType:@"mp3"]];
//视频来源
NSURL*videoInputUrl=[NSURLfileURLWithPath:[[NSBundlemainBundle]pathForResource:@"2016全球三
⼤超跑宣传⽚_超清"ofType:@"mp4"]];
//最终合成输出路径
NSString*outPutFilePath=[documentsstringByAppendingPathComponent:@"4"];
//添加合成路径
NSURL*outputFileUrl=[NSURLfileURLWithPath:outPutFilePath];
//时间起点
CMTimenextClistartTime=kCMTimeZero;
//创建可变的⾳视频组合
AVMutableComposition*comosition=[AVMutableCompositioncomposition];
//视频采集
AVURLAst*videoAst=[[AVURLAstalloc]initWithURL:videoInputUrloptions:nil];
//视频时间范围
CMTimeRangevideoTimeRange=CMTimeRangeMake(kCMTimeZero,on);
//视频通道枚举kCMPersistentTrackID_Invalid=0
AVMutableCompositionTrack*videoTrack=[comosition
addMutableTrackWithMediaType:AVMediaTypeVideopreferredTrackID:kCMPersistentTrackID_Invalid];
//视频采集通道
AVAstTrack*videoAstTrack=[[videoAsttracksWithMediaType:AVMediaTypeVideo]firstObject];
//把采集轨道数据加⼊到可变轨道之中
[videoTrackinrtTimeRange:videoTimeRangeofTrack:videoAstTrackatTime:nextClistartTimeerror:nil];
//声⾳采集
AVURLAst*audioAst=[[AVURLAstalloc]initWithURL:audioInputUrloptions:nil];
//因为视频短这⾥就直接⽤视频长度了,如果⾃动化需要⾃⼰写判断
CMTimeRangeaudioTimeRange=videoTimeRange;
//⾳频通道
AVMutableCompositionTrack*audioTrack=[comosition
addMutableTrackWithMediaType:AVMediaTypeAudiopreferredTrackID:kCMPersistentTrackID_Invalid];
//⾳频采集通道
AVAstTrack*audioAstTrack=[[audioAsttracksWithMediaType:AVMediaTypeAudio]firstObject];
//加⼊合成轨道之中
[audioTrackinrtTimeRange:audioTimeRangeofTrack:audioAstTrackatTime:nextClistartTimeerror:nil];
//创建⼀个输出
AVAstExportSession*astExport=[[AVAstExportSessionalloc]initWithAst:comosition
pretName:AVAstExportPretMediumQuality];
//输出类型
FileType=AVFileTypeQuickTimeMovie;
//输出地址
URL=outputFileUrl;
//优化
OptimizeForNetworkU=YES;
//合成完毕
[astExportexportAsynchronouslyWithCompletionHandler:^{
//回到主线程
dispatch_async(dispatch_get_main_queue(),^{
//调⽤播放⽅法outputFileUrl这个就是合成视频跟⾳频的视频
[lfplayWithUrl:outputFileUrl];
});
}];
}
本文发布于:2023-01-03 11:47:09,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/84231.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |