1
votes

I'm here again looking for help with AVFoundation. Sorry for my not perfect English.

I'm programming video editor now. At first i load video from library and put it to AVAsset instance. Then, every time when user select some video area and set speed parameter there, i do something like this:

AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                           preferredTrackID:kCMPersistentTrackID_Invalid];

[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(startOfEditedFrame, 600))
                           ofTrack:[self.videoAsset tracksWithMediaType:AVMediaTypeVideo][0] atTime:mixComposition.duration error:&error];

[track insertTimeRange:CMTimeRangeFromTimeToTime(CMTimeMakeWithSeconds(startOfEditedFrame, 600), CMTimeMakeWithSeconds(endOfEditedFrame, 600))
                           ofTrack:[self.videoAsset tracksWithMediaType:AVMediaTypeVideo][0] atTime:mixComposition.duration error:nil];

[track scaleTimeRange:CMTimeRangeFromTimeToTime(CMTimeMakeWithSeconds(startOfEditedFrame, 600), CMTimeMakeWithSeconds(endOfEditedFrame, 600))
                    toDuration:CMTimeMultiplyByFloat64(CMTimeMakeWithSeconds(endOfEditedFrame - startOfEditedFrame, 600), 1/[self.speeds[self.currentFrameStartIndex] floatValue])];

[track insertTimeRange:CMTimeRangeFromTimeToTime(CMTimeMakeWithSeconds(endOfEditedFrame, 600), self.videoAsset.duration)
                           ofTrack:[self.videoAsset tracksWithMediaType:AVMediaTypeVideo][0] atTime:mixComposition.duration error:nil];

self.videoAsset = mixComposition;

First time it's working OK, but second time i have "insertTimeRange" mistakes and zero duration of composition. Please, let me know if you have any ideas what goes wrong here or any suggestions how to do it differently/more correctly.

2
I am facing the same issue.Have you find the solution? - Reckoner

2 Answers

1
votes

Looks like I have a got a solution to this problem.You cannot edit an AVMutableComposition multiple times like you have been trying to.

It will work ok for the first time because right now its an AVAsset that you have made from a url(any url).So after you do editing for the first time, the asset changes its form.It nomore remains an AVAsset but now it is AVMutableComposition.So you need to export the composition with a new url and then make a new AVAsset with that url and then perform this code on that asset and it will definitely work.

Elaborated reason: Here are some suggestions for you that will help you understand each bit of it.

1.When you try to edit an asset multiple times without exporting.
This is what an asset looks like the first time you are performing some editing on it.

    <AVURLAsset: 0x7ff6404736c0, URL = file:///Users/puneetgurtoo/Library/Developer/CoreSimulator/Devices/8CC36C99-62B4-47F4-82BB-205DFE93FD96/data/Containers/Data/Application/26EFAB87-EA98-47DD-B7D9-A28CEE0DA043/Documents/28DBF785-58A4-4F3D-9AF0-77E300D89658-1595-000008AB6974EF7A.mov>

But when you have done a editing operation on it,after that it becomes something like this:

    AVMutableComposition: 0x7ff640403e50 tracks = (
"<AVMutableCompositionTrack: 0x7ff64046bb90 trackID = 1, mediaType = vide, editCount = 1>",
"<AVMutableCompositionTrack: 0x7ff64046c490 trackID = 2, mediaType = soun, editCount = 1>"
)>

That is where the problem occurs.

2.So when you export an AVMutableComposition with a newURL,just create a new instance of AVAsset with that url and the problem will be solved.

I will be posting the link to a demo version of the same later today.Till then you can go through this concept.

0
votes

One pointer I can give you is to look on the header file of AVMutableComposition.

The comments for the insertTimeRange method talks about the tracks parameter:

Specifies the asset that contains the tracks that are to be inserted. Only instances of AVURLAsset are supported.

So the tracks you are inserting from tracks must be of the AVURLAsset class and this class only.