我知道 Android 的 MediaPlayer
是个很棒的东西。它允许我们播放本地文件和媒体流。而且它非常易于使用(仅作为示例):
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("http://streaming.shoutcast.com/80sPlanet"); // this steam broadcasts audio/mpeg
mediaPlayer.prepareAsync();
mediaPlayer.start();
可以通过使用不同的参数集调用重载的 setDataSource()
来设置不同类型的数据源。
这个函数有一个有趣的原型(prototype):
void setDataSource(MediaDataSource dataSource)
看起来可以用您自己的实现完全覆盖 DataSource
。它确实有效:
import android.media.MediaDataSource;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
public class UrlMediaDataSource extends MediaDataSource {
URL url;
HttpURLConnection connection;
BufferedInputStream stream;
public UrlMediaDataSource(URL url) throws IOException {
this.url = url;
connection = (HttpURLConnection) url.openConnection();
}
@Override
public long getSize() {
return 0;
}
@Override
public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
if (stream == null)
stream = new BufferedInputStream(connection.getInputStream());
return stream.read(buffer, offset, size);
}
@Override
public void close() throws IOException {
stream.close();
stream = null;
connection.disconnect();
connection = null;
}
}
在主要代码中:
UrlMediaDataSource dataSource = new UrlMediaDataSource(new URL("http://streaming.shoutcast.com/80sPlanet"));
mediaPlayer.setDataSource(dataSource);
是的,这很好用。但是,如果我尝试使用音频/aacp 广播流(例如:“http://111.223.51.8:8005”——它是“COOLfahrenheit 93”广播),播放器不会播放。 Logcat 跟踪:
06-07 23:26:01.680 1352-1147/? E/GenericSource: Failed to init from data source!
06-07 23:26:01.681 1352-1093/? D/NuPlayerDriver: notifyListener_l(0xf3e051e0), (100, 1, -2147483648)
06-07 23:26:01.735 1352-2013/? D/NuPlayerDriver: reset(0xf3e051e0)
06-07 23:26:01.735 1352-2013/? D/NuPlayerDriver: notifyListener_l(0xf3e051e0), (8, 0, 0)
06-07 23:26:01.736 1352-1093/? D/NuPlayerDriver: notifyResetComplete(0xf3e051e0)
不过,当没有使用自定义 MediaDataSource
时,URL 工作正常(音乐播放):
mediaPlayer.setDataSource("http://111.223.51.8:8005");
有人知道管理这个的正确方法吗?
只是不要建议我直接使用 URL
- 我需要自定义 MediaDataSource
来访问流的原始数据。
最佳答案
The main point is that the
MediaPlayer
does playback audio/mpeg (both ways - through URL and through customMediaDataSource
), but audio/aacp streams could be played back only via URL asDataSource
.
那么,让我们了解幕后发生的事情。
当您将 URL 作为数据源传递时,然后 this正在执行检查:
if ("file".equals(scheme)) {
path = uri.getPath();
} else if (scheme != null) {
// handle non-file sources
nativeSetDataSource(
MediaHTTPService.createHttpServiceBinderIfNecessary(path),
path,
keys,
values);
return;
}
媒体播放器
uses MediaHTTPService
类,which is responsible用于提供来自 http
、https
和 widevine
协议(protocol)的数据。 MediaHTTPService
内部使用 MediaHTTPConnection
,这需要处理那种类型的流的所有繁重工作。不幸的是,这些 API 尚未公开,但您可以在 MediaHTTPConnection
中看到如何建立连接。来源(特别是 seekTo
method )。因此,您提供给 MediaPlayer
的自定义数据源应该描述大致的逻辑,即 MediaHTTPConnection
类实现。
关于java - 如何将自定义 android.media.MediaDataSource 与 android.media.MediaPlayer 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44424424/