下面的方法可行,因为m4a文件被保存在本地的res/raw目录中。

MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();

The following doesn't work. (But does with MP3's).

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

谁能解释一下为什么当m4a音频文件不是本地的时候会失败?

Here's (some of) the error...

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)   

我的目标是SDK 1.6。

2 个评论
你混淆了编码和文件格式。 AAC是一种音频编码格式。 M4A是一种文件类型,或包,围绕AAC数据。 3GPP是类似的,但可以包含其他类型的编码音频。 请看这里developer.android.com/guide/appendix/media-formats.html和这里en.wikipedia.org/wiki/M4a.
bdls
的确,我应该把3GPP和M4A描述为AAC音频的 "容器"。在我的脑海中,我thinkM4A可能只用于静态文件,而3GPP只能使用RTSP而不是HTTP流媒体?这将导致HTTP流的问题。如果我说错了,请纠正我...
android
audio
aac
m4a
bdls
bdls
发布于 2009-10-31
5 个回答
bdls
bdls
发布于 2009-12-31
已采纳
0 人赞同

This 变通办法 allows you to play M4A files from the net (and AAC files in other containers such as MP4 & 3GP). It simply downloads the file and plays from the cache.

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
            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();
    
好主意,但当然这需要先下载整个文件才能播放。 在某些情况下可能是有用的,但显然不适合作为流媒体解决方案。
bdls
这是真的,尽管这段代码可以用来创建一个流媒体解决方案,使用一个或多个本地文件作为临时的循环缓冲区。不幸的是,MediaPlayer不能从InputStream中接收,否则你就可以用标准的方式做一个循环缓冲区。
Cristofer
Cristofer
发布于 2009-12-31
0 人赞同

I tried it too but I could not find out the solution!

在上一次谷歌I/O大会上,我看到了对我帮助很大的东西。它是从MediaPlayer扩展而来,改善了很多东西看一下吧。

exoplayer可以帮助你很多

看看这部分的例子。

private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int BUFFER_SEGMENT_COUNT = 256;
// String with the url of the radio you want to play
String url = getRadioUrl();
Uri radioUri = Uri.parse(url);
// Settings for exoPlayer
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo");
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT);
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
// Prepare ExoPlayer
exoPlayer.prepare(audioRenderer);

EXOPLAYER-我可以从流媒体(视频和音频)中播放任何东西!

LET ME KNOW IF YOU NEED HELP TO IMPLEMENT IT! :)

Goyuix
Goyuix
发布于 2009-12-31
0 人赞同

这是在黑暗中的胡乱猜测,但我看到Flash播放器有类似的行为,它实际上忽略了文件名,只依赖服务器发送的MIME类型。你知道什么是头文件吗?例子.com?你可能想试试把你的blah.m4a包装在一个可以设置头文件的页面中,然后把二进制数据流化。给这些类型一个机会,社区会感谢你对工作的确认。

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

bdls
一个好的建议 - 谢谢。不幸的是,我尝试了一系列可能的内容类型都没有成功。作为参考,我在下面列出了那些没有工作的内容。这仍然有可能是与HTTP头文件有关的问题--或者其他问题--可能是它对可以被输入的内容非常挑剔。 【替换代码0
我确实遇到过这样的问题。 对于我们的流媒体目的,MediaPlayer不会播放流媒体文件,除非Http头的内容类型设置正确。 有趣的是,内容长度并不是必需的。
Hashim Akhtar
Hashim Akhtar
发布于 2009-12-31
0 人赞同

我发现,如果你在安卓系统上用以下属性录制音频文件,那么你就能在你的服务器上播放它。它在HTML音频元素中也能很好地播放,不过目前只在Firefox上。这在将来可能会改变。

安卓(JAVA)。

mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setOutputFile(filePath);

HTML:

<audio id="audioMediaControl" controls src="yourfile.m4a"> Your browser does not support the audio element. </audio>

subbarao
subbarao
发布于 2009-12-31
0 人赞同