当前位置: 首页 > 面试题库 >

如何将自定义android.media.MediaDataSource与android.media.MediaPlayer一起使用?

蒋健
2023-03-14
问题内容

我知道Android MediaPlayer很棒。它使我们能够播放本地文件以及媒体流。而且非常容易使用(例如):

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("http://streaming.shoutcast.com/80sPlanet"); // this steam broadcasts audio/mpeg
mediaPlayer.prepareAsync();
mediaPlayer.start();

通过调用setDataSource()具有不同参数集的重载,可以设置不同类型的DataSource 。这个函数有一个有趣的原型:

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)

不过,在不使用自定义网址的情况下,URL可以正常播放音乐(播放音乐)MediaDataSource

mediaPlayer.setDataSource("http://111.223.51.8:8005");

有谁知道正确的方法来管理这个?只是不要建议我URL直接使用-我需要一个自定义项MediaDataSource来访问流的原始数据。


问题答案:

要点是,它MediaPlayer确实可以播放 音频/ mpeg (通过URL和自定义两种方式MediaDataSource),但是
音频/ aacp 流只能通过URL像一样播放DataSource

因此,让我们了解幕后情况。

当您将URL作为数据源传递时,将执行以下检查:

    if ("file".equals(scheme)) {
        path = uri.getPath();
    } else if (scheme != null) {
        // handle non-file sources
        nativeSetDataSource(
            MediaHTTPService.createHttpServiceBinderIfNecessary(path),
            path,
            keys,
            values);
        return;
    }

MediaPlayer
使用
MediaHTTPService类,它负责提供从数据httphttpswidevine协议。MediaHTTPService在内部使用MediaHTTPConnection,使用这种类型的流需要花费大量的精力。不幸的是,这些API尚未公开(但是),但是您可以看到如何在MediaHTTPConnection源中建立连接(特别是seekTomethod)。因此,您提供的自定义数据源MediaPlayer应该大致描述MediaHTTPConnection该类实现的逻辑。



 类似资料:
  • 问题内容: 我只是开始看一下Mattt出色的新Alamofire快速联网库,并且不确定如何将其与自定义标头一起使用。 我正在尝试从AFNetworking转换为Alamofire的代码是这样的: 问题答案: 根据官方文档,不建议修改会话配置: 不建议将其用于Authorization或Content- Type标头。而是分别使用URLRequestConvertible和ParameterEnco

  • 我正在将我的Spring应用程序从Spring-boot 1.5.9迁移到Spring-boot 2.0.0。使用这个新的Spring包,我在Redis中缓存数据时遇到了一些问题。 在我的配置中,我有3个具有不同TTL(长、中、短)的CacheManager: 我还有一个自定义RestTemplate: 在上一个Spring版本中,缓存的每个数据都使用这个RestTemplate,并使用Gener

  • 问题内容: 我还没有找到一种方法来做到这一点。可能吗? 问题答案: 好吧,我无法弄清楚如何使用可用的类,因此我自己扩展了它,现在它对我有用。这是我所做的:

  • 问题内容: 我正在尝试使用两个SingleColumnValueFilter对象从HBase表中过滤行,以带回属于该列的长值范围内的所有记录。根据SingleColumnValueFilter的文档,除非您将其传递给自己的比较器,否则它将对列值进行字典比较。该API显示了SingleColumnValueFilter,其中采用WritableByteArrayComparable作为实现此目的的方

  • 如何将自定义摄取管道与Filebeat模块一起使用?在我的例子中,我使用的是<code>apache<code>模块。 根据多个来源,这应该可以通过<code>output.elasticsearch进行配置。管道/。资料来源如下: https://www.elastic.co/guide/en/beats/filebeat/current/elasticsearch-output.html#pi

  • 我很难用Filebeat的Docker自动发现功能来使用定制的Elasticsearch摄取管道。我已经在我的< code>filebeat.yml文件中开始使用自定义处理器,但是我更愿意将它转移到我创建的自定义摄取管道。 首先,这是我使用自定义处理器的配置,它为我的Servarr应用Docker容器提供自定义的类似grok的处理(通过在我的docker-compose.yml文件中对它们应用标签