【问题标题】:Play media from from zip file without unzipping从 zip 文件播放媒体而不解压缩
【发布时间】:2013-02-24 19:36:31
【问题描述】:

我知道在 SO 上已经有一些类似的问题,但它们与在播放之前提取文件有关。

在 Android 文档 here 中解释说,您可以直接从 .zip 文件播放文件而无需解压。

提示:如果您要将媒体文件打包成 ZIP,您可以使用 media 播放带有偏移和长度控制的文件调用(例如 MediaPlayer.setDataSource() 和 SoundPool.load()) 无需 解压缩您的 ZIP。为了使它工作,你不能执行 创建 ZIP 时对媒体文件进行额外压缩 包。例如,使用 zip 工具时,应使用 -n 用于指定不应压缩的文件后缀的选项:

zip -n .mp4;.ogg main_expansion media_files

我制作了一个(未压缩的)zip 包,但我不知道如何从ZipEntryFileDescriptor,他们也没有进一步解释。如何在不解压缩 zip 文件的情况下获得FileDescriptor

【问题讨论】:

  • zip file format 使用相当简单的内部文件结构。头指向数据,所以你只需要寻找文件头,然后使用Relative offset of local file headerCompressed size找到数据的开始和它的长度。你也应该至少检查Compression method以确保文件未压缩,只要它没有压缩,使用数据,否则先解压缩数据,然后使用它。
  • 压缩方法是store 使用7zip,.zip 文件的大小等于解压缩文件的总和,所以我认为我已经正确压缩了它们。除此之外,我不知道你在说什么:P
  • 不久前我遇到了同样的问题,但没有任何运气让它工作。您可以查看这些问题了解更多详情:stackoverflow.com/questions/12863731/…stackoverflow.com/questions/12920429/…

标签: android zip android-mediaplayer


【解决方案1】:

即使您的应用中没有使用 APK 扩展,您也可以使用 APK 扩展 Zip 库来做到这一点。

按照此文档获取库:Using the APK Expansion Zip Library

使用您喜欢的压缩工具不压缩压缩您的声音文件。

使用此代码加载音乐:

ZipResourceFile expansionFile = new ZipResourceFile("myZipFile.zip");
AssetFileDescriptor assetFileDescriptor = expansionFile.getAssetFileDescriptor("myMusic.mp3");
try {
    mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor());
    mediaPlayer.prepare();
    mediaPlayer.start();
}
catch (IOException e) {
    // Handle exception
}

【讨论】:

  • 我已经转向其他方法,但如果有人能证实这一点,我很乐意接受。
  • 如果 zip 文件被压缩,这似乎不起作用。
  • myZipFile.zip 应该位于哪个文件夹?
【解决方案2】:

这个问题最近没有很多解决方案,所以我也被困在这个问题上——直到我在尝试读取 zip 文件的函数中创建了一个新的 MediaPlayer 实例。突然开始播放没有问题。现在,相反,我将我的(全局)MediaPlayer 传递给这样的函数:(Kotlin)

private fun preparePlayer(mp: MediaPlayer, position: Int) {

    // Path of shared storage
    val root: File = Environment.getExternalStorageDirectory()
    Log.i("ROOT", root.toString())

    // path of the zip file
    val zipFilePath = File(root.absolutePath+"/Android/obb/MY_PACKAGE_NAME/MY_ZIP_FILE.zip")

    // Is zip file recognized?
    val zipFileExists = zipFilePath.exists()
    Log.i("Does zip file exist?", zipFileExists.toString())

    // Define the zip file as ZipResourceFile
    val expansionFile = ZipResourceFile(zipFilePath.absolutePath)

    // Your media in the zip file
    val afd = expansionFile.getAssetFileDescriptor("track_01.mp3")

    // val mp = MediaPlayer()   // not necessary if you pass it as a function parameter
    mp.setDataSource(afd.fileDescriptor, afd.startOffset, afd.length)
    mp.prepare()
    mp.start()   // Music should start playing automatically

也许这可以帮助其他人。祝你好运!

【讨论】:

    【解决方案3】:
    try {
        ZipFile zf= new ZipFile(filename);
        ZipEntry ze = zip.getEntry(fileName);
        if (ze!= null) {
            InputStream in = zf.getInputStream(ze);
            File f = File.createTempFile("_AUDIO_", ".wav");
            FileOutputStream out = new FileOutputStream(f);
            IOUtils.copy(in, out);
            // play f
        }
    } catch (IOException e) {
    
    }
    

    possible duplicate question

    【讨论】:

    • 感谢您的示例,但我已经知道如何创建临时文件。问题是关于在不解压缩文件的情况下访问文件。不过,如果没有主要的骗局,这似乎是不可能的。
    • 哦,那我可能被误解了。因为我从来没有发现像在不解压缩或不使用临时文件的情况下播放文件这样的东西。我怀疑你是否能找到一种方法。如果有的话分享一下就太好了。
    【解决方案4】:

    如果您想在不解压缩的情况下使用 zip 中的媒体文件,您还必须将起始偏移量和长度添加到 setDataSource

    ZipResourceFile expansionFile = new ZipResourceFile("myZipFile.zip");
    AssetFileDescriptor assetFileDescriptor = expansionFile.getAssetFileDescriptor("myMusic.mp3");
    try {
        mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(),
                                  assetFileDescriptor.getStartOffset(),
                                  assetFileDescriptor.getLength());
        mediaPlayer.prepare();
        mediaPlayer.start();
    }
    catch (IOException e) {
        // Handle exception
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多