avmutablecomposition - AVFoundation concatenating videos -
i pulling hair out on this.
i try concatenate videos , won't want do. specifically, have videos have different orientation , try set right layer instruction. alas, not matter try, has no effect...
i read every tutorial, tried implement aplcompositiondebugview provided apple (which looks ok), no avail... i'm ready throw overboard...
here's code:
self.videocomposition = [avmutablevideocomposition videocomposition]; self.videocomposition.rendersize = cgsizemake(480, 320); self.videocomposition.frameduration = cmtimemake(1, 30); nsmutablearray *videocompositioninstructions = [[nsmutablearray alloc] init]; avmutablecomposition *themutablecomposition = [avmutablecomposition composition]; avmutablecompositiontrack *compositionvideotrack = [themutablecomposition addmutabletrackwithmediatype:avmediatypevideo preferredtrackid:kcmpersistenttrackid_invalid]; avmutablecompositiontrack *compositionaudiotrack = [themutablecomposition addmutabletrackwithmediatype:avmediatypeaudio preferredtrackid:kcmpersistenttrackid_invalid]; avmutablevideocompositionlayerinstruction *passthroughlayer = [avmutablevideocompositionlayerinstruction videocompositionlayerinstructionwithassettrack:compositionvideotrack]; cmtime titleduration = cmtimemakewithseconds(5, 600); cmtimerange titlerange = cmtimerangemake(kcmtimezero, titleduration); [compositionvideotrack insertemptytimerange:titlerange]; [compositionaudiotrack insertemptytimerange:titlerange]; cmtime insertpoint = [[transitiontimes lastobject] cmtimevalue]; cmtime totaltime = cmtimemakewithseconds(5, 600); for(nsdictionary *clip in collection[@"clips"]){ nsstring *moviename = [nsstring stringwithformat:@"collection_%li/recording_%li_%li.mov", (long)editcollection, editcollection, [clip[@"clipid"] longvalue]]; nsurl *asseturl = [nsurl fileurlwithpath:[usefulstuff pathforfile: moviename]]; avurlasset *videoasset = [avurlasset urlassetwithurl:asseturl options:nil]; totaltime = cmtimeadd(totaltime, videoasset.duration); avassettrack *clipvideotrack = [[videoasset trackswithmediatype:avmediatypevideo] objectatindex:0]; avassettrack *clipaudiotrack = [[videoasset trackswithmediatype:avmediatypeaudio] objectatindex:0]; nserror *error; [compositionvideotrack inserttimerange:clipvideotrack.timerange oftrack:clipvideotrack attime:insertpoint error:&error]; // add video [compositionaudiotrack inserttimerange:clipvideotrack.timerange oftrack:clipaudiotrack attime:insertpoint error:&error]; // add audio [passthroughlayer settransform:clipvideotrack.preferredtransform attime:insertpoint]; ////// should supposedly set video in right orientation @ given time... insertpoint = cmtimeadd(insertpoint, videoasset.duration); } avmutablevideocompositioninstruction *passthroughinstruction = [avmutablevideocompositioninstruction videocompositioninstruction]; passthroughinstruction.timerange = cmtimerangemake(kcmtimezero, totaltime); nslog(@"total time b %f", cmtimegetseconds(totaltime)); passthroughinstruction.layerinstructions = [nsarray arraywithobject:passthroughlayer]; [videocompositioninstructions addobject:passthroughinstruction]; self.videocomposition.instructions = videocompositioninstructions; heeeeeeelp! :)
i don't see in posted code deals orientation problem. need transform in layerinstruction make orientation same.
try this:
avmutablecomposition *composition = [avmutablecomposition composition]; avmutablecompositiontrack *compositionvideotrack = [composition addmutabletrackwithmediatype:avmediatypevideo preferredtrackid:kcmpersistenttrackid_invalid]; avmutablevideocomposition *videocomposition = [avmutablevideocomposition videocomposition]; videocomposition.frameduration = cmtimemake(1,30); videocomposition.renderscale = 1.0; avmutablevideocompositioninstruction *instruction = [avmutablevideocompositioninstruction videocompositioninstruction]; avmutablevideocompositionlayerinstruction *layerinstruction = [avmutablevideocompositionlayerinstruction videocompositionlayerinstructionwithassettrack:compositionvideotrack]; // paths user selected nsmutablearray *array = [nsmutablearray array]; for(nsstring* string in videopatharray){ if(![string isequaltostring:@""]){ [array addobject:string]; } } self.videopatharray = array; float time = 0; (int = 0; i<self.videopatharray.count; i++) { avurlasset *sourceasset = [avurlasset urlassetwithurl:[nsurl fileurlwithpath:[videopatharray objectatindex:i]] options:[nsdictionary dictionarywithobject:[nsnumber numberwithbool:yes] forkey:avurlassetpreferprecisedurationandtimingkey]]; nserror *error = nil; bool ok = no; avassettrack *sourcevideotrack = [[sourceasset trackswithmediatype:avmediatypevideo] objectatindex:0]; cgsize temp = cgsizeapplyaffinetransform(sourcevideotrack.naturalsize, sourcevideotrack.preferredtransform); cgsize size = cgsizemake(fabsf(temp.width), fabsf(temp.height)); cgaffinetransform transform = sourcevideotrack.preferredtransform; videocomposition.rendersize = sourcevideotrack.naturalsize; if (size.width > size.height) { [layerinstruction settransform:transform attime:cmtimemakewithseconds(time, 30)]; } else { float s = size.width/size.height; cgaffinetransform new = cgaffinetransformconcat(transform, cgaffinetransformmakescale(s,s)); float x = (size.height - size.width*s)/2; cgaffinetransform newer = cgaffinetransformconcat(new, cgaffinetransformmaketranslation(x, 0)); [layerinstruction settransform:newer attime:cmtimemakewithseconds(time, 30)]; } ok = [compositionvideotrack inserttimerange:sourcevideotrack.timerange oftrack:sourcevideotrack attime:[composition duration] error:&error]; if (!ok) { // deal error. nslog(@"something went wrong"); } nslog(@"\n source asset duration %f \n source vid track timerange %f %f \n composition duration %f \n composition vid track time range %f %f",cmtimegetseconds([sourceasset duration]), cmtimegetseconds(sourcevideotrack.timerange.start),cmtimegetseconds(sourcevideotrack.timerange.duration),cmtimegetseconds([composition duration]), cmtimegetseconds(compositionvideotrack.timerange.start),cmtimegetseconds(compositionvideotrack.timerange.duration)); time += cmtimegetseconds(sourcevideotrack.timerange.duration); } instruction.layerinstructions = [nsarray arraywithobject:layerinstruction]; instruction.timerange = compositionvideotrack.timerange; videocomposition.instructions = [nsarray arraywithobject:instruction]; i have taken code here because works me every time. have make resulting transform according requirement.
Comments
Post a Comment