我有我自己的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) = "2017 年 7 月 24 日星期一 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>此流需要 <a href="http://www.winamp.com" >Winamp</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:无法打开 libwvm.so:dlopen 失败:找不到库“libwvm.so” 07-24 18:11:49.962 7408-7671/com.sample.sandbox V/播放器:mime:音频/mpeg 07-24 18:11:49.964 7408-7681/com.sample.sandbox I/OMXClient:使用客户端 OMX 多路复用器。 07-24 18:11:50.170 7408-7681/com.sample.sandbox I/MediaCodec:MediaCodec 将在异步模式下运行 [...]
似乎一切正常(流实际上是通过设备播放的)。
但是,如果我尝试打开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>此流需要 <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:无法打开 libwvm.so:dlopen 失败:找不到库“libwvm.so” 07-24 18:38:45.425 32284-32690/com.sample.sandbox E/PlayerThread: 错误 java.io.IOException:无法实例化提取器。 在 android.media.MediaExtractor.setDataSource(本机方法) 在 com.sample.sandbox.Player.open(Player.java:204) 在 com.sample.sandbox.Player.<init>(Player.java:231) 在 com.sample.sandbox.PlayerThread.run(PlayerThread.java:28)
有谁知道是什么问题?问题绝对不在流本身 - 它是完全有效的。