Reputation: 3523
I wanna get number of frames from video.. I m using following code:
package com.vidualtest;
import java.io.File;
import java.io.FileDescriptor;
import android.app.Activity;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Bundle;
import android.os.Environment;
import android.widget.ImageView;
public class VidualTestActivity extends Activity {
/** Called when the activity is first created. */
File file;
ImageView img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img = (ImageView) findViewById(R.id.img);
File sdcard = Environment.getExternalStorageDirectory();
file = new File(sdcard, "myvid.mp4");
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(file.getAbsolutePath());
img.setImageBitmap(retriever.getFrameAtTime(10000,MediaMetadataRetriever.OPTION_CLOSEST));
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (RuntimeException ex) {
ex.printStackTrace();
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
}
}
}
}
here in getFrameAtTime() i m passing different static time like 10000,20000, etc. in milliseconds , but still i'm getting same frame from video within different time. My aim is to get different frames with different time interval.
Please get me your possible help.
Thanks
Upvotes: 12
Views: 29895
Reputation: 2976
public Bitmap getFrameAtTime (long timeUs, int option)
Someone missed to document that timeUs
is expected to be microseconds, not milliseconds for this method. You can find that hint in other methods doc:
timeUs long: The time position in microseconds
Make sure to multiply your millis by a 1000
retriever.getFrameAtTime(1000000, Int) // returns the frame after one second
Upvotes: 1
Reputation: 34360
if Your video is of 10s . if you want to take a frame after 1 second you increment it 1000000 which means after 1sec.
I have stored id of image view in an array..
int[] ids_of_images = new int[]{R.id.img,R.id.img2,R.id.img3,R.id.img4,R.id.img5};
looper =1000000;
and then
for(int i=0 ;i <10; i++)
{
ImageView imageView = (ImageView)findViewById(ids_of_images[i]);
imageView.setImageBitmap(retriever.getFrameAtTime(looper,MediaMetadataRetriever.OPTION_CLOSEST));
looper +=1000000;
}
I have tested it .. It is running . I have make ten ImageView and read frame like above
Upvotes: 4
Reputation: 3150
With the jCodec library, I'm able to get all frames efficiently with this code to get all the video's frames:
private class Decoder extends AsyncTask<File, Integer, Integer> {
private static final String TAG = "DECODER";
protected Integer doInBackground(File... params) {
FileChannelWrapper ch = null;
try {
ch = NIOUtils.readableFileChannel(params[0]);
FrameGrab frameGrab = new FrameGrab(ch);
MediaInfo mi = frameGrab.getMediaInfo();
Bitmap frame = Bitmap.createBitmap(mi.getDim().getWidth(), mi.getDim().getHeight(), Bitmap.Config.ARGB_8888);
for (int i = 0; !flag; i++) {
frameGrab.getFrame(frame);
if (frame == null)
break;
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(new File(params[0].getParentFile(), String.format("img%08d.jpg", i))));
frame.compress(CompressFormat.JPEG, 90, os);
} finally {
if (os != null)
os.close();
}
publishProgress(i);
}
} catch (IOException e) {
Log.e(TAG, "IO", e);
} catch (JCodecException e) {
Log.e(TAG, "JCodec", e);
} finally {
NIOUtils.closeQuietly(ch);
}
return 0;
}
@Override
protected void onProgressUpdate(Integer... values) {
progress.setText(String.valueOf(values[0]));
}
}
Upvotes: 1
Reputation: 870
The time offset parameter is in microseconds, not milliseconds. So multiply your time offset by 1000, and it should work correctly.
Thank you Google for NOT specifying this in the documentation.
Upvotes: 37
Reputation: 2920
I think getFrameAt() returns the frame thats closest to the time interval you specify. So specifying 1000 or 1500 as the time (in milliseconds) might return the same frame if the frame that's closest to both those time intervals is the same. To get the number of frames, you might want to get repetitive frames and then check whether they are distinct by just checking a few pixels. But you'll have to make sure that you don't miss any frames.
Upvotes: 0