当MediaPlayer在不同的位置播放时,如何从只读的RandomAccessFile中读取

时间:2013-03-22 13:21:15

标签: android media-player randomaccessfile

我有一个自定义文件格式(类似于zip文件),它将小文件(小图像,mp3文件)打包成1个物理文件。我的Android应用程序下载此文件,它会显示一个图像。用户可以触摸图像,它将开始播放其中一个小mp3"文件"在打包文件中。他也可以向左或向右滑动,应用程序会显示上一张或下一张图片。

为了让事情变得更顺畅,我持有3"卡"在记忆中:当前显示的那个,以及前一个和下一个。这样,当它被刷过时,我可以立即显示下一张图像。为了做到这一点,我正在将图像和mp3预加载到MediaPlayer中。问题是因为它是多线程的,因为预加载是在后台完成的。我有一个错误:当我开始播放mp3时,在它播放过程中我会滑动,我preaload的图像在中间切割。经过大量调试后,我找到了原因:当我加载图像时,MediaPlayer正在移动文件描述符中的文件指针,这导致下一次读取从mp3的中间读取而不是图像。

以下是代码:

InputStream imageStream = myPackedFile.getBaseStream("cat.jpg"); // this returns an InputStream representing "cat.jpg" from my packed file (which is based on a RandomAccessFile)
Drawable image = Drawable.createFromStream(imageStream, imagePath);

FileDescriptor fd = myPackedFile.getFD();
long pos = myPackedFile.getPos("cat.mp3");
long len = myPackedFile.getLength("cat.mp3");
player.setDataSource(fd, pos, len);
player.prepare();

2 个答案:

答案 0 :(得分:1)

这对我有用:我创建一个文件,而不是创建一个RandomAccessFile,并且每次我需要以RandomAccessFile的形式访问它时,我创建一个新文件:

public class PackagedFile {
    private File file;
    PackagedFile(String filename) {
        file = new File(filename);
    }
    public RandomAccessFile getRandomAccessFile() {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "r");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return raf;
    }
}

以上代码变为:

InputStream imageStream = myPackedFile.getBaseStream("cat.jpg"); // this returns an InputStream representing "cat.jpg" from my packed file (which is based on a RandomAccessFile)
Drawable image = Drawable.createFromStream(imageStream, imagePath);

FileDescriptor fd = myPackedFile.getRandomAccessFile().getFD();
long pos = myPackedFile.getPos("cat.mp3");
long len = myPackedFile.getLength("cat.mp3");
player.setDataSource(fd, pos, len);
player.prepare();

答案 1 :(得分:1)

对于API Level 13及更高版本,可以考虑ParcelFileDescriptor.dup复制文件描述符。有关详细信息,请参阅此链接:http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#864