Search code examples
androidaudio-playerandroid-cursoropus

Find opus files on Android


Since recently I'm using the OPUS file format in my music library. Even though Android seems to support the OPUS file format natively there are not many music players listing music tracks encoded in this format.

I've wanted to create my own simple music player listing OPUS encoded audio tracks. However I couldn't figure out how to find the files on the system.

The best way would be to use a query/cursor. However OPUS files are just ignored:

Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                                           null, null, null, null);

System.out.println(cursor.getCount()); //The size of my music library without .opus files

while (cursor.moveToNext()) {
  //.mp3 and .flac files but no .opus files
  System.out.println(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));
}

Then I tried to access my music files manually but without success:

File musicDirectory = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC).toURI());
//This directory seems to be empty, length: 0
System.out.println(musicDirectory.list().length);

And:

File file = new File(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.getPath());
//Exists: false
System.out.println(file.exists());

Has anybody got any idea what the problem is, or know any workarounds? Any help would be appreciated.


Solution

  • The best way would be to use a query/cursor. However OPUS files are just ignored

    If your Opus files are of a similar vintage as your MP3 and FLAC files (i.e., they have been on your test device for a long time), then MediaStore might not know to automatically index them.

    Then I tried to access my music files manually but without success:

    There are few problems here:

    • The File constructor and toURI() stuff is pointless, as getExternalFilesDir() returns a File
    • That File points to your app-specific portion of external storage, so unless your Opus files are there, this File will not list them
    • If you wanted to switch to the device-level music directory (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)), that is not available to you on Android 10 and higher

    And:

    A Uri is not a file. Calling getPath() on a Uri whose scheme is anything other than file is pointless, and the scheme for MediaStore.Audio.Media.EXTERNAL_CONTENT_URI is content

    know any workarounds?

    You could try your MediaStore query, but:

    • Constrain based on MIME type, and
    • Use MediaStore.Files instead of MediaStore.Audio

    That too will not work on Android 10 and higher, but if it worked it would be faster than scanning the music directory tree yourself.

    And unless MediaStore.Audio starts indexing Opus files, there is no great solution for you on Android 10 and higher. The best would be ACTION_OPEN_DOCUMENT_TREE, so the user can point you to a document tree containing Opus files, and you would scan that tree for documents with the Opus MIME type. That might work, but it may also be slow.