【问题标题】:How to stream authenticated content with MediaPlayer on Android如何在 Android 上使用 MediaPlayer 流式传输经过身份验证的内容
【发布时间】:2011-02-25 07:37:34
【问题描述】:

我在 SO 上看到很多帖子问这个问题,但似乎没有明确的答案(或者至少是我喜欢的答案!)

我的内容受到基本身份验证(用户名/密码)的保护——我可以使用各种 HTTP 下载类很好地下载它,但对于我来说,我无法弄清楚如何告诉媒体播放器流式传输它(并提供身份验证)。我看到一篇帖子暗示这是不可能的,因为 MediaPlayer 都是本机代码,不像 Authenticator。

有很多关于如何首先下载到缓存副本然后播放的示例,但是....那种糟透了(文件可能有 100 个 MB)。我看到至少一个建议以小块下载它,然后开始和停止播放(重定向到新文件),但这也很糟糕,因为(我认为)会出现口吃(虽然我还没有尝试过) )

此时我的最佳想法是开始下载到缓存文件,然后当它“足够”时开始播放,同时我继续填充文件......我希望这可行(但同样,还没有尝试过)。

我是否遗漏了一些明显的东西?让所有不同的部分几乎都能正常工作真是太痛苦了,我有点说服自己,必须有一种方法来本地流式传输受保护的内容(或者让它采用已经建立和合格的 InputStream),但这似乎并不快乐。

顺便说一句,我是 Mac/iPhone 用户,也是 Android 的新手,所以我仍在努力学习一点 Java。如果我遗漏了一些明显的东西,请原谅。

【问题讨论】:

  • 来自developer.android.com/guide/topics/media/index.html, "注意:如果您将 URL 传递给在线媒体文件,该文件必须能够进行渐进式下载。"如果不是这样,它会发布一些代码。
  • 嘿@loghound 你找到解决方案了吗?除了您的考虑之外,我还在考虑使用 cookie 之类的东西来存储凭据,也许 android 流功能会抓住它。
  • 我还发现您无法流式传输 HTTPS。作为一种解决方法,我们实现了渐进式播放,它可以工作,但它需要很多代码。
  • 从未找到答案,但有人建议只打开一个网络视图并使用普通的 html/javascript 进行身份验证(这是个好主意,但我从未走得那么远)
  • @OliverMoffat 我不知道这是不是真的,我现在可以流式传输 HTTPS 内容了。

标签: android authentication streaming media-player


【解决方案1】:

如果您控制服务器,一个选项可能是对其进行修改,以便可以选择在身份验证时为内容生成一个临时的随机 URL,然后将其流式传输。流式处理函数是否会接受包含脚本参数的 URL?

要完全在手机上做事,另一种选择是用 java 或本机代码编写一个简单的 http 代理,如服务器,并在后台线程中运行。您无需将媒体播放器指向服务器,而是将其指向您自己的设备代理。代理将请求传递到远程服务器,同时处理身份验证。

【讨论】:

    【解决方案2】:

    一种方法是自己下载数据,将其解码(从??? 到 PCM)并使用 AudioTrack 播放 PCM。诀窍在于解码。流是用什么格式编码的?

    常见协议的原始解码器在 Android 上可用,但在 C 库中。因此,您可能必须再次添加一个 JNI 层来进行解码,具体取决于您的流采用什么编码。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,我通过将凭据放入 URL 中解决了这个问题。 HTTP 并未正式支持它,但大多数 Web 客户端都支持它。

      以下代码基于本教程:http://www.coderzheaven.com/2012/08/14/stream-audio-android/

          try {
              // You can use HTTPS or HTTP as protocol.
              String myURL = "https://example.com/song.mp3";
      
              mp.reset();
              mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
              mp.setOnPreparedListener(this);
              mp.setOnErrorListener(this);
      
              // These are the two lines, doing the magic ;) It transforms it to a url like this: https://user:password@example.com/song.mp3
              UsernamePasswordCredentials credentials = connHelper.getCredetials();
              myURL = myURL.replace("://", "://" + URLEncoder.encode(credentials.getUserName(), "UTF-8") + ":" + URLEncoder.encode(credentials.getPassword(), "UTF-8") + "@");
      
              mp.setDataSource(myURL);
              mp.prepareAsync();
              mp.setOnCompletionListener(this);
          } catch (Exception e) {
              Log.e("StreamAudioDemo", e.getMessage());
          }
      

      注意:通过在此处使用 URLEncoder,我们希望解决以下问题:如果用户名或密码包含冒号或 @。

      注意 2: 它可能适合您,也可能不适合您,具体取决于您的服务器。如果你遇到这个问题,我建议你看看那个:Why do browsers not send the Authentication header when the credentials are provided in the URL?

      【讨论】:

        猜你喜欢
        • 2013-08-28
        • 1970-01-01
        • 1970-01-01
        • 2021-09-24
        • 2019-03-20
        • 2012-06-23
        • 2019-09-25
        • 1970-01-01
        • 2016-01-17
        相关资源
        最近更新 更多