FrameGrabber
FrameGrabber copied to clipboard
Nice Work!
Hi Arthur
First of all I want to say that I really enjoyed looking through your project. It is very well organized and cleanly written. It was quite helpful to refresh my memory on how AVAssetImageGenerator works.
That said, I had issues using the FrameExport class, specifically the generateAndExportFrames
method. While efficient, it produced out of sequence files, so that reassembling the sequential output produced a stuttering animation.
I am still looking into this, but perhaps you've already encountered this issue, and know how to resolve it? I am exporting a .mov file so that I can create an animated UIImage. I create the animation by loading the exported frames sequentially into UIImage.animatedImages. What I'm finding is that the exported images move forward, then a little back, and then forward again over and over again...
On line 50 of FrameExportOperation.swift: let frameIndex = self.frameStartIndex + countProcessed
this index is used to determine the output filename for the processed frame. Because files are processed in chunks (of 5) any of these files can be ready/completed out of sequence. Presumably the easiest to process of the 5 will be ready first and will get the next available sequence/frame/index number. This would account for the out-of-sequence images.
I grabbed ffmpeg and used the following command:
ffmpeg -i "IMG_3689.mov" "frames/out-%03d.jpg"
and the results gave me a series of files in the correct order and they animate fine in my UIImageView. That told me it is possible to extract the frames in the correct order.
I changed the chunk size to 1, presuming that this would eliminate any concurrency, and that the indexes would be in correct sequence. But this didn't solve the problem. (if it had, I would have determined the fix and sent you the code)
So I don't know if this is a bug in AVAssetImageGenerator.generateCGImagesAsynchronously (I don't find anything online, so I don't think this is the case), or if there might be some concurrency going on that I didn't notice.
I will continue to look into this an keep you updated, but I don't want to waste my time if this is an issue you've already addressed.
The next thing I will try is either:
- to move all processing onto a dedicated serial queue and bypass the OperationQueues. (a lot of work for another "test") Or
- package the index/sequence number with the CMTime into a struct and post a notification with the resulting image and sequence number attached -- if I can find a place in the code where this is possible. I am using a singleton FileExportDataModel, and could add an observer to receive these and write out the file.
Let me know if you have any thoughts, ideas, frustrations, encouragement....
M