This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Just checking references here, but what is the actual value of the String variable METADATA_KEY_DURATION when you extract it and max after you parse it into an int? It's not very likely, but since the variable name and the key constant have the same name I want to make sure you aren't getting scoping problems. Also, can you verify that the loop itself is running more than once?
The value for METADATA_KEY_DURATION (as the String) is 7100 (presumably milliseconds). There is no issue w/ scoping as the parameter passed into the method is scoped to MediaMetadataRetriever while the variable getting assigned is scoped to the method.
Yes the for loop is executing that many times: I have a Log.d statement that I see.
Since presumably the value of max is 7100 (no errors parsing into an int), then only the first seven iterations of the loop would actually pull a frame time inside the video's duration. With index = 8, the requested frame time is already past the video duration at 8 seconds (8,000,000us), index = 10 -> 10 seconds, etc. So all subsequent 7090 iterations probably continuously pull the last readable frame; perhaps try and change the requested time so you get better granularity of presentation time values (i.e. so all values of the loop are within the duration). Technically, though, we would expect at least a few of the first seven requests to be different frames (unless the video really has very few sync frames in it), so...
Another thing that has given me issues in the past is trying to use the OPTION_CLOSEST flag; it seems that some device implementations are unable to read anything but sync frames out of encoded media types. Perhaps try a different flag that specifically only reads back the sync frames from the content.
So in other words, try modifying the frame request like so:
Joined: Mar 16, 2007
For my original code, yes, I would have expected there to be more than just one image saved.
Thanks for the advice. After the code change, unfortunately, same as before, it only saved the first frame.
My loop now looks like the following:
By the way I have also tried the following with the same results of just one image:
I have taken and run your original code, along with the modifications you made, on my Nexus S device and everything basically works as expected. Depending on the options selected, a 14s test video produces around 24 images (OPTION_CLOSEST_SYNC) or 240 images (OPTION_CLOSEST). I do not have Droid X2 hardware, but I also ran this code in the Motorola Droid X emulator, which uses the same software image so the performance should be comparable, and the results where the same there as well.
This leads me to believe that the issue lies either with the video you are reading or with that device, because I cannot find any further fault with your code and it seems to be working from the tests I've run.
Joined: Mar 16, 2007
I just shot 2 more videos: 4-5 seconds each. One is done w/ the phone in portrait and one w/ phone in landscape. For me, both still produced the same results.
They are either my left or right hand counting to 3 or 4. JavaRanch doesn't appear to support a single file that is 13megs (.7z)
Can you post your video that I can try? Or can I post my video for you to download and try?
It's not a programmable thing, sync frames are a concept of encoding video. Encoded video files don't store every video frame of data to keep the file size down. They only save specific frames known as "key frames" or "sync frames" as a full frame, and then just the pixel deltas for frames in between. This is why, by default, sync frames are all the retriever returns; it's easier to find them and extra decoding doesn't need to be done. How many sync frames are inserted in the video file is up to the application that encoded it (on the desktop, it's usually a programmable setting of the encoding software) and I'm sure it's a fixed value on the device.
It's theoretically possible that a video file have only the initial frame fully rendered, although unlikely as playback would be very slow. However, having issues with the MP4 I used rules out the camera's recording capability as the problem.
My code does not create any IMG files.
Interesting, in your initial post you mentioned you were getting only one initial frame, now you are getting zero. I wonder how just a different movie file could affect things in that way...are you able to get your code working in the emulator?
Joined: Mar 16, 2007
I meant to say my code does not write more than 1 .png w/ your mp4 file that I downloaded.