问题
I've set up ExoPlayer to stream audio and it works beautifully on some devices I have (eg, my Nexus 5) but on others it simply doesn't play anything at all.
To eliminate any issues with my app, I've modified the demo app by changing the "Dizzy" video to a random MP3 I've got sitting on a server. In DefaultRendererBuilder I'm also returning a null video track renderer and am only attempting to play audio.
Obviously each device has its own set of codecs and so I suspected that maybe the wrong one was getting loaded and breaking. I've seen a couple of points in the ExoPlayer source where a decoder is determined from a MIME type and I think I've narrowed it down to a line in FrameworkSampleSource
in the prepare
method.
As soon as setDataSource
is called, on the Huawei Mate 7 device I'm using, all hell breaks loose. It looks like the MediaExtractor
uses FFMPEG to extract the data, which does not seem to be compatible. Other devices I've tested with do not appear to do this. Here's the dump from LogCat
11-13 16:30:45.600 30793-30793/com.google.android.exoplayer.demo I/ExoPlayerImpl﹕ Init 1.0.13
11-13 16:30:45.605 30793-30881/com.google.android.exoplayer.demo I/﹕ uri = http://this-is-my-server.com/public/mime-test.mp3
11-13 16:30:45.605 30793-30881/com.google.android.exoplayer.demo I/﹕ after judge whether is youtube , isWidevine = 0
11-13 16:30:45.605 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractor﹕ FFMPEGExractor opened file is [http://this-is-my-server.com/public/mime-test.mp3]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo E/FFMPEGExtractor﹕ Can not find video stream!
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo E/FFMPEGExtractorUtils﹕ Couldn't find MIME by codec id 86017 !
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractor﹕ Unknown MIME,try using ffmpegaudiodecorder to decode
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractor﹕ setAudioMeta MIME = audio/ffmpeg
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractor﹕ audio/ffmpeg set kKeyFFmpegCodecID,codec->codec_id = 86017
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ Audio:
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ {
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ kKeyMIMEType = [audio/ffmpeg]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ kKeyDuration = [00:01:43.42]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ kKeyBitRate = [128000 bps]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ kKeyChannelCount = [1]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ kKeySampleRate = [44100 bps]
11-13 16:30:45.790 30793-30881/com.google.android.exoplayer.demo I/FFMPEGExtractorUtils﹕ }
11-13 16:30:45.790 30793-30883/com.google.android.exoplayer.demo I/OMXClient﹕ Using client-side OMX mux.
11-13 16:30:45.795 30793-30883/com.google.android.exoplayer.demo I/MediaCodec﹕ Found 0 pieces of codec specific data.
11-13 16:30:45.795 30793-30883/com.google.android.exoplayer.demo I/ACodec﹕ allocateBuffersOnPort,isHevc = 0
11-13 16:30:45.795 30793-30883/com.google.android.exoplayer.demo I/ACodec﹕ allocateBuffersOnPort,isHevc = 0
11-13 16:30:47.210 30793-30881/com.google.android.exoplayer.demo W/FFMPEGExtractor﹕ retry to read pakcet
11-13 16:30:47.210 30793-30881/com.google.android.exoplayer.demo W/FFMPEGExtractor﹕ retry to read pakcet
11-13 16:30:47.210 30793-30881/com.google.android.exoplayer.demo W/FFMPEGExtractor﹕ retry to read pakcet
11-13 16:30:47.210 30793-30881/com.google.android.exoplayer.demo W/FFMPEGExtractor﹕ retry to read pakcet
11-13 16:30:47.210 30793-30881/com.google.android.exoplayer.demo E/FFMPEGExtractor﹕ Reaching the end of file! streamId : 0
As you can see, it doesn't seem to be able to detect the MIME type properly. If I pass in the EXACT SAME file that's a local version on disk, it'll play just fine, just not if it's on the server. FFMPEG doesn't seem to understand what the MIME is and just uses its own bastardised "audio/ffmeg" mime instead. It seems to get the duration and such, but just cannot play the file.
If I set a listener on ExoPlayer, I can see it move through each of the states - preparing, buffering, but NEVER ready. It will move from 'buffering' to 'ended'.
While I'm not sure this is an ExoPlayer-specific issue, surely someone must have encountered something similar to this? It's a pretty basic use-case - just playing an MP3 using the lines -
SampleSource sampleSource = new FrameworkSampleSource(context, uri, headers, RENDERER_COUNT);
audioTrackRenderer = new MediaCodecAudioTrackRenderer(sampleSource, null, true);
Nothing too exciting there. What am I doing wrong? What can I do to work around it? I've even passed in "Content-Type": "audio/mpeg" as a header and it does nothing.
回答1:
Exoplayer now has an application-level media extractor (currently on the dev branch) which avoids this issue entirely as it doesn't run through Android's broken MediaExtractor.
Check out the demo app's PlayerActivity and ExtractorRendererBuilder to get an idea of how to use it.
回答2:
To me this looks like a bug specific to Huawei Mate 7 's Android framework. The bug is that MediaExtractor does not work correctly for server hosted MP3 files. You could prove it by using the same server hosted MP3 URL and play it using some other app that uses Android's MediaPlayer. You will find innumerable sample code or APKs that use MediaPlayer online.
Quick google search gave http://examples.javacodegeeks.com/android/android-mediaplayer-example/ http://code.tutsplus.com/tutorials/create-a-music-player-on-android-song-playback--mobile-22778
来源:https://stackoverflow.com/questions/26902670/exoplayer-doesnt-play-audio-on-devices-which-use-ffmpeg