使用Android流式传输AAC音频

bdl*_*dls 20 audio android aac m4a

据我了解,如果编码为MPEG-4或3GPP,Android将只播放AAC格式的音频.

当它在应用程序的本地时,我能够播放编码为M4A的AAC音频,但是当从服务器获取它时它会失败.

以下工作,因为m4a文件本地保存在res/raw目录中.

MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();
Run Code Online (Sandbox Code Playgroud)

以下不起作用.(但MP3的确如此).

Uri uri = Uri.parse("http://*example.com*/blah.m4a");
MediaPlayer mp = MediaPlayer.create(this, uri);
mp.start();
Run Code Online (Sandbox Code Playgroud)

当m4a音频文件不是本地时,任何人都可以解释它失败的原因吗?

这是(一些)错误......

ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus
ERROR/MediaPlayer(769): error (200, -32)  
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete  
DEBUG/MediaPlayer(769): create failed:  
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8  
DEBUG/MediaPlayer(769):     at android.media.MediaPlayer.prepare(Native Method)  
DEBUG/MediaPlayer(769):     at android.media.MediaPlayer.create(MediaPlayer.java:530)  
DEBUG/MediaPlayer(769):     at android.media.MediaPlayer.create(MediaPlayer.java:507)   
...
Run Code Online (Sandbox Code Playgroud)

我的目标是SDK 1.6.

bdl*_*dls 5

这种解决方法允许您从网络播放M4A文件(以及其他容器中的AAC文件,如MP4和3GP).它只是下载文件并从缓存中播放.

private File mediaFile;

private void playAudio(String mediaUrl) {
    try {
        URLConnection cn = new URL(mediaUrl).openConnection();
        InputStream is = cn.getInputStream();

        // create file to store audio
        mediaFile = new File(this.getCacheDir(),"mediafile");
        FileOutputStream fos = new FileOutputStream(mediaFile);   
        byte buf[] = new byte[16 * 1024];
        Log.i("FileOutputStream", "Download");

        // write to file until complete
        do {
            int numread = is.read(buf);   
            if (numread <= 0)  
                break;
            fos.write(buf, 0, numread);
        } while (true);
        fos.flush();
        fos.close();
        Log.i("FileOutputStream", "Saved");
        MediaPlayer mp = new MediaPlayer();

        // create listener to tidy up after playback complete
        MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                // free up media player
                mp.release();
                Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released");
            }
        };
        mp.setOnCompletionListener(listener);

        FileInputStream fis = new FileInputStream(mediaFile);
        // set mediaplayer data source to file descriptor of input stream
        mp.setDataSource(fis.getFD());
        mp.prepare();
        Log.i("MediaPlayer", "Start Player");
        mp.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好主意但当然这要求在播放之前先下载整个文件.可能对某些情况有用,但显然不适合作为流媒体解决方案. (5认同)

Goy*_*uix 0

这是在黑暗中的疯狂拍摄,但我在 Flash 播放器中看到了类似的行为,它实际上忽略了文件名,仅依赖于服务器发送的 MIME 类型。知道example.com正在发送哪些标头吗?您可能想尝试将 blah.m4a 包装在可以设置标头然后流式传输二进制数据的页面中。尝试一下这些类型,社区会很高兴确认哪些方法有效:

音频/mpeg 音频/mp4a 音频/mp4a-latm 音频/aac 音频/x-aac