ios - AVAssetExportSession ignoring videoComposition rotation & stripping metadata -
i attempting rotate video prior upload on ios device because other platforms (such android) not interpret rotation information in ios-recorded videos and, result, play them improperly rotated.
i have looked @ following stack posts have not had success apply of them case:
i coped apple avsimpleeditor project sample, unfortunately ever happens is, upon creating avassetexportsession , calling exportasynchronouslywithcompletionhandler, no rotation performed, , what's worse, rotation metadata stripped out of resulting file.
here code runs export:
avassetexportsession *exportsession = [[avassetexportsession alloc] initwithasset:[_mutablecomposition copy] presetname:avassetexportpresetpassthrough]; exportsession.outputurl = outputurl; exportsession.outputfiletype = avfiletype3gpp; exportsession.shouldoptimizefornetworkuse = yes; exportsession.videocomposition = _mutablevideocomposition; [exportsession exportasynchronouslywithcompletionhandler:^(void) { nslog(@"status %d %@", exportsession.status, exportsession.error); handler(exportsession); [exportsession release]; }];
the values _mutablecomposition , _mutablevideocomposition initialized method here:
- (void) getvideocomposition:(avasset*)asset { avmutablecomposition *mutablecomposition = nil; avmutablevideocomposition *mutablevideocomposition = nil; avmutablevideocompositioninstruction *instruction = nil; avmutablevideocompositionlayerinstruction *layerinstruction = nil; cgaffinetransform t1; cgaffinetransform t2; avassettrack *assetvideotrack = nil; avassettrack *assetaudiotrack = nil; // check if asset contains video , 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 composition given asset , insert audio , video tracks asset // check whether composition has been created, i.e, other tool has been applied // create new composition mutablecomposition = [avmutablecomposition composition]; // insert video , audio tracks 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 composition compensate movement caused rotation (since rotation cause move out of frame) t1 = cgaffinetransformmaketranslation(assetvideotrack.naturalsize.height, 0.0); // rotate transformation t2 = cgaffinetransformrotate(t1, degreestoradians(90.0)); // step 3 // set appropriate render sizes , rotational transforms // create new video composition mutablevideocomposition = [avmutablevideocomposition videocomposition]; mutablevideocomposition.rendersize = cgsizemake(assetvideotrack.naturalsize.height,assetvideotrack.naturalsize.width); mutablevideocomposition.frameduration = cmtimemake(1, 30); // rotate transform set on 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 transform instructions video composition instruction.layerinstructions = @[layerinstruction]; mutablevideocomposition.instructions = @[instruction]; tt_release_safely(_mutablecomposition); _mutablecomposition = [mutablecomposition retain]; tt_release_safely(_mutablevideocomposition); _mutablevideocomposition = [mutablevideocomposition retain]; }
i pulled method avserotatecommand from here. can suggest why method not rotate video necessary 90 degrees?
because using avassetexportpresetpassthrough
avassetexportsession
ignore videocomposition
, use other preset.
Comments
Post a Comment