我们正在使用 MediaRecorder 将视频记录到外部存储器上的文件中,并在进行实际录制之前使用 setOutputFile()。
一切都很顺利,但主要问题是,一旦录制完成,我们希望在 VideoView 中开始播放录制的视频。
如何知道文件何时准备好以便读取和回放?
我们正在使用 MediaRecorder 将视频记录到外部存储器上的文件中,并在进行实际录制之前使用 setOutputFile()。
一切都很顺利,但主要问题是,一旦录制完成,我们希望在 VideoView 中开始播放录制的视频。
如何知道文件何时准备好以便读取和回放?
FileObserver
类完全符合您的需求。 这里是文档。它易于使用。当观察到的文件在写入后关闭时,将调用onEvent
回调,并将CLOSE_WRITE
作为参数。
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()
。
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.stop()都是一种阻止方法,仅在媒体记录器完全写入并关闭文件后才返回。
因此,JPM的答案实际上是正确的。
您可以通过立即调用File.length()来验证此操作。您会发现输出文件长度此时是文件的最终长度。换句话说,在stop()返回后,媒体记录器不会再向文件中写入任何内容。
我自己没有尝试过,但这可能有效:
public void release () Since: API Level 1
释放与此 MediaRecorder 对象关联的资源。当您完成使用 MediaRecorder 后,调用此方法是一个好习惯。
如果它做到了它所说的,那么我猜如果你调用这个方法并且在这个方法返回后,你就知道文件已经准备好了。
显然在媒体播放器中没有办法检测录制何时停止,但是如果您创建一个实现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();
}
}
然后您可以访问布尔值以查看是否已停止录制。
lastModified()
值,并在文件未被修改2秒钟后打开VideoView。
onEvent
中进行检查。如果录制已暂停,只需忽略该事件即可。 - RonFileObserver
时需要注意的是它并不像宣传的那样监视单个文件,而是监视整个目录。因此,请监视目录以便检测变化。在onEvent(int event, String path)
中,实际受影响的文件路径将作为String
参数传递。然后,您可以将该路径与您感兴趣的文件路径进行比较,并相应地做出响应。有关更多信息,请参见 https://dev59.com/JWQn5IYBdhLWcg3w9K73。 - Tash Pemhiwa