我想从视频中获取帧数...我使用以下代码:
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) {
}
}
}
}
这里的getFrameAtTime()我以毫秒为单位传递不同的静态时间,如10000,20000等,但我仍然在不同的时间内从视频中获取相同的帧。我的目标是获得不同时间间隔的不同帧。
请给我你可能的帮助。
由于
答案 0 :(得分:28)
时间偏移参数以微秒为单位,而不是毫秒。因此,将您的时间偏移乘以1000,它应该可以正常工作。
感谢Google未在文档中指定此内容。
答案 1 :(得分:3)
如果您的视频是10秒。如果您想在1秒后拍摄一帧,则将其增加1000000,这意味着在1秒后。
我已将图像视图的id存储在数组中..
int[] ids_of_images = new int[]{R.id.img,R.id.img2,R.id.img3,R.id.img4,R.id.img5};
looper =1000000;
然后
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;
}
我测试了它..它正在运行。我已经制作了十张ImageView并像上面一样读取了框架
答案 2 :(得分:2)
尝试Microseconds,它应该可以工作!
答案 3 :(得分:1)
使用jCodec library,我可以使用此代码有效地获取所有帧,以获取所有视频的帧:
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]));
}
}
答案 4 :(得分:0)
我认为getFrameAt()返回最接近您指定时间间隔的帧。因此,如果最接近这两个时间间隔的帧相同,则指定1000或1500作为时间(以毫秒为单位)可能会返回相同的帧。要获得帧数,您可能希望获得重复帧,然后通过检查几个像素来检查它们是否是不同的。但是你必须确保你不会错过任何帧。
答案 5 :(得分:0)
public Bitmap getFrameAtTime (long timeUs, int option)
有人忘记记录 timeUs
预计为微秒,而不是此方法的毫秒。您可以在 other methods doc 中找到该提示:
timeUs long:以微秒为单位的时间位置
确保将您的毫秒乘以 1000
retriever.getFrameAtTime(1000000, Int) // returns the frame after one second