从扩展文件中读取mp3

6

从扩展文件中读取mp3文件

我已经创建了一个名为

"main.1.com.example.app.obb"

的扩展文件,其中包含一个音频文件名为"about_eng.mp3"

现在问题是,我编写了以下代码来读取和播放mp3文件

    private final static String EXP_PATH = "/Android/obb/";

static String[] getAPKExpansionFiles(Context ctx, int mainVersion, int patchVersion) {
    String packageName = ctx.getPackageName();
    Vector<String> ret = new Vector<String>();
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        // Build the full path to the app's expansion files
        File root = Environment.getExternalStorageDirectory();
        File expPath = new File(root.toString() + EXP_PATH + packageName);

        // Check that expansion file path exists
        if (expPath.exists()) {
            if ( mainVersion > 0 ) {
                String strMainPath = expPath + File.separator + "main." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strMainPath);
                if ( main.isFile() ) {
                        ret.add(strMainPath);
                }
            }
            if ( patchVersion > 0 ) {
                String strPatchPath = expPath + File.separator + "patch." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strPatchPath);
                if ( main.isFile() ) {
                        ret.add(strPatchPath);
                }
            }
        }
    }
    String[] retArray = new String[ret.size()];
    ret.toArray(retArray);
    return retArray;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    // Get a ZipResourceFile representing a merger of both the main and patch files

    try {
        ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(this,1,1);
        if(expansionFile!=null){

            AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("about_eng.mp3");
                //or
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource( fd.getFileDescriptor(), 
                    fd.getStartOffset(),fd.getLength());
            mediaPlayer.prepare();
            mediaPlayer.start();

            }




    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // Get an input stream for a known file inside the expansion file ZIPs


}

但是它总是在这一行抛出异常。
 mediaPlayer.setDataSource( fd.getFileDescriptor(), 
                    fd.getStartOffset(),fd.getLength());
            mediaPlayer.prepare();

因为变量fd为空。请问有谁能帮我解决这个问题?

我认为这篇文章可以帮助你:https://dev59.com/zmjWa4cB1Zd3GeqPvvfq - Klem
请检查您的zip文件是否未压缩。如果zip文件被压缩,“getAssetFileDescriptor”将返回null。 - Klem
你解决了吗?我也遇到了同样的问题。https://dev59.com/_m3Xa4cB1Zd3GeqPgZnh - Bhavesh Hirpara
3个回答

8
我已经搜索并发现我们应该使用“0%(无压缩)”的.zip文件,这在http://developer.android.com/google/play/expansion-files.html中有提到。
提示:如果您将媒体文件打包成ZIP格式,则可以对这些文件使用带有偏移和长度控制的媒体播放调用(例如MediaPlayer.setDataSource()和SoundPool.load()),而无需解压缩ZIP文件。为使此功能正常工作,创建ZIP包时不得对媒体文件执行额外的压缩。例如,在使用zip工具时,您应该使用-n选项来指定不应压缩的文件后缀: zip -n .mp4;.ogg main_expansion media_files
因此,如何使用winrar创建0%压缩的zip文件呢? enter image description here 请参考上图中的压缩方法。
然后,我们需要将此zip文件上传到Play商店。 因此,您不需要使用其他SO答案中提到的ZipHelper.java,只需简单地使用它即可。
ZipResourceFile expansionFile=null;

            try {
                expansionFile = APKExpansionSupport.getAPKExpansionZipFile(getApplicationContext(),3,0);

                     AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("test.mp3");
                     MediaPlayer mPlayer = new MediaPlayer();
                     mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                     mPlayer.setDataSource(fd.getFileDescriptor(),fd.getStartOffset(),fd.getLength());
                     mPlayer.prepare();
                     mPlayer.start();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

1
谢谢,不要忘记偏移量和长度,否则它将从压缩文件中的第一个mp3开始播放。 - Ehsan

1
尝试使用expansionFile.getAssetFileDescriptor("main_expansion/about_eng.mp3")
如果不起作用,请调用此函数: ZipResourceFile.ZipEntryRO [] entries = expansionFile.getAllEntries(); 并查看文件名: entries[0].mFileName;
这可能是路径应该看起来像的提示。
我知道这个问题很旧了,但也许能帮助某些人。

0

使用MediaPlayer读取mp3文件,有三种方法可供选择。

例如,我的应用程序包名称为

com.bluewindsolution.android.sampleapp

那么我的扩展文件应该是

main.1.com.bluewindsolution.android.sampleapp.obb

详细信息,请在这里查看

[主文件|补丁文件].<扩展版本号>.<包名>.obb


从扩展中,您可以通过以下3种方式获取它:

通过AssetFileDescriptor

// this one work with image file, media file
// Get a ZipResourceFile representing a specific expansion file
// mainContext, version no. of your main expansion, version no of your patch
ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(this, 1, 0); 
AssetFileDescriptor afd_img1 = expansionFile.getAssetFileDescriptor("your_path/your_file.jpg");
AssetFileDescriptor afd_mpbg = expansionFile.getAssetFileDescriptor("your_path/your_file.mp3");

// to set image
ImageView imageView1 = (ImageView)findViewById(R.id.iv1); 
imageView1.setImageBitmap(BitmapFactory.decodeFileDescriptor(afd_iv1.getFileDescriptor()));

// to set sound
try {
    mpbg.setDataSource(afd_mpbg.getFileDescriptor(), afd_mpbg.getStartOffset(), afd_mpbg.getDeclaredLength());
    mpbg.prepareAsync();
    mpbg.start();
} catch (IllegalStateException e) {
    Log.w("Error=====", "Failed to prepare media player", e);
}

通过 InputStream

// this one work with image file, media file
// Get a ZipResourceFile representing a specific expansion file

ZipResourceFile expansionFile = new ZipResourceFile(filePathToMyZip);

// Get an input stream for a known file inside the expansion file ZIPs

InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);

通过 Uri

//this one can use in almost thing such as jpg, mp3, mp4, pdf, etc.

//you need to create new class to override APEZProvider
public class ZipFileContentProvider extends APEZProvider {
    @Override
    public String getAuthority() {
        return "com.bluewindsolution.android.sampleapp";
    }
}

//you need to add <provider> in AndroidManifest.xml
<provider
 android:name="com.bluewindsolution.android.sampleapp.ZipFileContentProvider"
   android:authorities="com.bluewindsolution.android.sampleapp" 
      android:exported="false"
      android:multiprocess="true"
    >
    <meta-data android:name="mainVersion"
              android:value="1"></meta-data>
</provider>

//after that you can use it any time by this code:
String filename2 = "image/i_commu_a_1_1_1_1.jpg"; // suppose you store put your file in directory in .obb
String uriString2 = "content://com.bluewindsolution.android.sampleapp" +  File.separator + filename2;
Uri uri2 = Uri.parse(uriString2);
imageView2.setImageURI(uri2);

// Filename inside my expansion file
String filename = "video/v_do_1_1_1.mp4"; // suppose you store put your file in directory in .obb
String uriString = "content://com.bw.sample_extension_download_main" +  File.separator + filename;
Uri uri = Uri.parse(uriString);

v1 = (VideoView)findViewById(R.id.videoView1);
v1.setVideoURI(uri);
v1.start();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接