代码之家  ›  专栏  ›  技术社区  ›  Eugene

MediaExtractor不理解音频/aacp流

  •  0
  • Eugene  · 技术社区  · 7 年前

    MediaDataSource :

    
    
        class MyDataSource extends MediaDataSource {
            private static final String TAG = "MyDataSource";
            private HttpURLConnection connection;
            private BufferedInputStream inputStream;
    
            MyDataSource(@NonNull URL streamURL) throws Throwable {
                this.connection = (HttpURLConnection) streamURL.openConnection();
                this.connection.setRequestMethod("GET");
                this.connection.addRequestProperty("Icy-Metadata", "0");
                this.connection.connect();
                int responseCode = this.connection.getResponseCode();
                if (responseCode != 200)
                    throw new IOException("http response code " + responseCode);
                for (Map.Entry<String, List<String>> header: this.connection.getHeaderFields().entrySet()) {
                    for (String headerValue : header.getValue())
                        Log.v(TAG, "responseHeader(" + header.getKey() + ") = \"" + headerValue + "\"");
                }
                this.inputStream = new BufferedInputStream(connection.getInputStream());
            }
    
            @Override
            public long getSize() {
                return -1;
            }
    
            @Override
            public int readAt(long position, @NonNull byte[] buffer, int offset, int size) throws IOException {
                int bytesRead;
                int bytesReadTotal = 0;
                do {
                    bytesRead = this.inputStream.read(buffer, offset + bytesReadTotal, size - bytesReadTotal);
                    bytesReadTotal += bytesRead;
                } while(bytesRead != 0 && bytesReadTotal < size);
                return bytesReadTotal;
            }
    
            @Override
            public void close() {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                        inputStream = null;
                    }
                    if (connection != null) {
                        connection.disconnect();
                        connection = null;
                    }
                } catch(IOException e) {
                    Log.e(TAG, "close", e);
                }
            }
        }
    

    MP3 流(例如。 A.0.0.00Radio ):

    
    
        MyDataSource dataSource = new MyDataSource(new URL("http://streaming.shoutcast.com/80sPlanet"));
        MediaExtractor mediaExtractor = new MediaExtractor();
        mediaExtractor.setDataSource();
        MediaFormat mediaFormat = mediaExtractor.getTrackFormat(0);
        String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
        Log.v("Player", "mime: " + mime);
        mediaExtractor.selectTrack(0);
        MediaCodec mediaCodec = MediaCodec.createDecoderByType(mime);
        mediaCodec.configure(this.mediaFormat, null, null, 0);
        int sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        AudioTrack audioTrack = new AudioTrack(
            AudioManager.STREAM_MUSIC,
            sampleRate,
            AudioFormat.CHANNEL_OUT_STEREO,
            AudioFormat.ENCODING_PCM_16BIT,
            AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT),
            AudioTrack.MODE_STREAM);
        mediaCodec.setCallback(new MyCodecCallback());
        mediaCodec.start();
        audioTrack.play();
    

    我看到了以下内容 Logcat trace :

        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(null) = "HTTP/1.1 200 OK"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Access-Control-Allow-Headers) = "Origin, Accept, X-Requested-With, Content-Type"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Access-Control-Allow-Methods) = "GET, OPTIONS, HEAD"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Access-Control-Allow-Origin) = "*"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Cache-Control) = "no-cache, no-store"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Connection) = "close"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Content-Type) = "audio/mpeg"
        07-24 18:11:49.958 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Date) = "Mon, 24 Jul 2017 18:11:59 GMT"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Expires) = "Mon, 26 Jul 1997 05:00:00 GMT"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-br) = "128"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-genre) = "Decades,80s"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-name) = "A.0.0.00Radio:All 80s All The Time"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-notice1) = "<BR>This stream requires <a href="http://www.winamp.com">Winamp&lt/a><BR>"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-notice2) = "SHOUTcast DNAS/posix(linux x64) v2.5.1.725<BR>"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-pub) = "1"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-sr) = "44100"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(icy-url) = "http://a.0.00radio.com/80s/"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Pragma) = "no-cache"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(Server) = "Icecast 2.3.3-kh8"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Received-Millis) = "1500919909958"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Response-Source) = "NETWORK 200"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Selected-Protocol) = "http/1.1"
        07-24 18:11:49.959 7408-7671/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Sent-Millis) = "1500919909816"
        07-24 18:11:49.961 7408-7671/com.sample.sandbox E/WVMExtractor: Failed to open libwvm.so: dlopen failed: library "libwvm.so" not found
        07-24 18:11:49.962 7408-7671/com.sample.sandbox V/Player: mime: audio/mpeg
        07-24 18:11:49.964 7408-7681/com.sample.sandbox I/OMXClient: Using client-side OMX mux.
        07-24 18:11:50.170 7408-7681/com.sample.sandbox I/MediaCodec: MediaCodec will operate in async mode
        [...]
    

    看起来一切正常(流实际上正在通过设备播放)。
    但如果我试着打开 AAC 流(例如。 COOLfahrenheit 93 ):

    
    
        MyDataSource dataSource = new MyDataSource(new URL("http://111.223.51.8:8005"));
        [...]
    

    MediaExtractor

        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(null) = "HTTP/1.0 200 OK"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(content-type) = "audio/aacp"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-br) = "128"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-genre) = "Easy Listening, Pop"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-name) = "COOLfahrenheit 93 - (4)"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-notice1) = "<BR>This stream requires <a href="http://www.winamp.com">Winamp</a><BR>"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-notice2) = "SHOUTcast DNAS/posix(linux x64) v2.4.7.256<BR>"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-pub) = "1"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(icy-url) = "http://www.coolism.net"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Received-Millis) = "1500921523862"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Response-Source) = "NETWORK 200"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Selected-Protocol) = "http/1.0"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(X-Android-Sent-Millis) = "1500921523387"
        07-24 18:38:43.863 32284-32690/com.sample.sandbox V/MyDataSource: responseHeader(X-Clacks-Overhead) = "GNU Terry Pratchett"
        07-24 18:38:45.424 32284-32690/com.sample.sandbox E/WVMExtractor: Failed to open libwvm.so: dlopen failed: library "libwvm.so" not found
        07-24 18:38:45.425 32284-32690/com.sample.sandbox E/PlayerThread: error
                                                                                  java.io.IOException: Failed to instantiate extractor.
                                                                                      at android.media.MediaExtractor.setDataSource(Native Method)
                                                                                      at com.sample.sandbox.Player.open(Player.java:204)
                                                                                      at com.sample.sandbox.Player.<init>(Player.java:231)
                                                                                      at com.sample.sandbox.PlayerThread.run(PlayerThread.java:28)
    

    有人知道问题出在哪里吗?问题肯定不在流本身——它是完全有效的。
    1 回复  |  直到 7 年前
        1
  •  1
  •   Eugene    7 年前

    position MediaDataSource::readAt()
    结果是 MediaExtractor
    我注意到这些跳过的数量(及其范围)取决于内容类型以及特定的编解码器。我在这个问题上的主要观点是“ 媒体提取器 aacp

    推荐文章