如何知道MediaRecorder何时完成将数据写入文件

在使用setOutputFile()进行实际录制之前,我们使用MediaRecorder将video录制到外部存储器上的文件中。

一切工作正常,但主要的问题是,只要录制完成,我们要开始播放录像video回到VideoView。

如何知道文件何时准备好被读取和播放?

FileObserver类完全适合您的需求。 这里是文档 。 它易于使用。 当一个观察文件在写入后closures时,以CLOSE_WRITE作为参数调用onEventcallback。

 MyFileObserver fb = new MyFileObserver(mediaFile_path, FileObserver.CLOSE_WRITE); fb.startWatching(); class MyFileObserver extends FileObserver { public MyFileObserver (String path, int mask) { super(path, mask); } public void onEvent(int event, String path) { // start playing } } 

不要忘记调用stopWatching() ..

我们用下面的algorithm解决了类似的问题:

 while (file not complete) sleep for 1 sec read the fourth byte of the file if it is not 0 (contains 'f' of the 'ftyp' header) then file is complete, break 

关键在于MediaRecorder在最后时刻写入了ftyp框。 如果到位,那么文件是完整的。

我没有尝试过,但这可能会工作:

public void release()从以下版本开始:API Level 1

释放与此MediaRecorder对象关联的资源。 当您完成使用MediaRecorder时,最好调用此方法。

如果它的确如此,那么我想如果你调用这个方法,在这个方法返回之后你就知道这个文件已经准备好了。

在我的testing中,无论录制媒体的大小如何,Reorder.stop()都是一个阻塞方法,只有在文件被媒体logging器完全写入和closures后才会返回。

所以JPM的回答实际上是正确的。

你可以通过在stop()之后立即调用File.length()来validation。 你会发现输出文件的长度是这个文件的最后一个长度。 换句话说,媒体logging器在stop()返回后不会再向文件写入任何内容。

显然,在Media player中停止录制的时候没有办法检测,但是如果你创build一个实现MediaRecorder的自定义类,你可以重写stop()。 在这里我会做这样的事情:

 public class MyRecorder implements MediaRecorder { public boolean stopped; .... implement all the methods that MediaRecorder has making sure to call super for each method. @Override public void myStop() { this.stopped = true; super.stop(); } } 

然后你可以访问布尔值来查看它是否已经停止logging。

一个肮脏的方法是检查文件的lastModified()值,如果文件没有被修改2秒,打开VideoView。

我在xamarin中遇到了同样的问题,并尝试了所有这些解决scheme(除了Ash解决scheme)。 我最终解决这个问题的方法是在Reset之前和释放之前在releaseMediaRecorder()函数中调用下面的函数。

 mediaRecorder.setOutputFile("some new file")