【问题标题】:Reading mp3 from expansion file从扩展文件中读取 mp3
【发布时间】:2012-10-23 13:13:18
【问题描述】:

从扩展文件中读取 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 为空。

谁能帮我解决这个问题

【问题讨论】:

标签: android file mp3 expansion


【解决方案1】:

我用谷歌搜索发现我们必须使用0% (No compression) 制作.zip,这在http://developer.android.com/google/play/expansion-files.html 中提到

Tip: If you're packaging media files into a ZIP, you can use media playback calls on the files with offset and length controls (such as MediaPlayer.setDataSource() and SoundPool.load()) without the need to unpack your ZIP. In order for this to work, you must not perform additional compression on the media files when creating the ZIP packages. For example, when using the zip tool, you should use the -n option to specify the file suffixes that should not be compressed: zip -n .mp4;.ogg main_expansion media_files

so 如何使用 winrar 制作 0% 压缩的 zip?

这里看压缩方法

所以我们应该把这个 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();
            }

【讨论】:

  • 谢谢,不要忘记偏移量和长度,否则它会从 zip 文件中的第一个 mp3 开始播放。
【解决方案2】:

尝试使用expansionFile.getAssetFileDescriptor("main_expansion/about_eng.mp3")

如果它不起作用,请调用:

ZipResourceFile.ZipEntryRO [] entries = expansionFile.getAllEntries();

并查看文件名:

entries[0].mFileName;

这可能是路径应该是什么样子的提示。

我知道这个问题很老,但也许它对某人有帮助。

【讨论】:

    【解决方案3】:

    要阅读 mp3,使用媒体播放器,你可以做到 3 种方式

    例如。我的应用程序包名称是

    com.bluewindsolution.android.sampleapp

    那么我的扩展文件应该是

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

    详细可以关注here

    [main|patch]...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);
    }
    

    通过输入流

    // 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();
    

    【讨论】:

      猜你喜欢
      • 2018-07-08
      • 2015-05-05
      • 2019-11-13
      • 2011-04-30
      • 1970-01-01
      • 2016-04-06
      • 2021-03-11
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多