18

我意识到在 Android 中 HLS 的支持水平方面存在一些问题。我正在尝试编写一个小型视频播放器演示(在尽可能多的设备上工作);最好不使用第三方库;可以流式传输 HLS 视频。

注意:我目前正在 JellyBean 4.2.2 上进行测试,但可以访问其他版本

我已经设法使用 MediaPlayer 类,以便我的应用程序能够开始播放流(例如 Apple 的测试视频BipBopAll),但它似乎正在加载流的错误部分,因为视频似乎开始于 29 分钟(所以它在大约三十秒后完成)。

我使用的代码非常基本:

private void playTrack()
{   
    player = new MediaPlayer();

    try 
    {                   
        player.setDisplay(holder);
        player.setDataSource("http://devimages.apple.com/iphone/samples/bipbop
                              /bipbopall.m3u8");
        player.prepare();

    } 
    catch (...) 
    {
    }
    player.start();
}

更新:我已经在 ICS 4.0.4 上测试了相同的代码,它工作正常。在 3.0.1 中进行测试,在 15 分钟加载流,然后从那里正确运行。

我该怎么做才能确保流从头开始,并在多个 Android 版本上正确播放?

或者,我应该使用更好的实现吗?

4

4 回答 4

14

经过进一步调查,我发现以下信息可以帮助其他人在 Android 上运行 HLS 流。

编码 - 视频编码和分段设置会对视频支持的 Android 版本产生很大影响。我最终使用 HandBrake 创建了一个视频,设置如下:

  • MP4 文件
  • H.264;基线资料;3级
  • AAC 音频;44.1k;128 位(注意:我发现 JellyBean 对音频比 ICS/Honeycomb 更挑剔。一些音频比特率会创建 Jellybean 根本无法播放的视频。一般来说,单声道和低比特率音频似乎在 Jellybean 上效果更好)。

分割- 使用 Apple MediaFileSegmenter,我发现添加“-no-floating-point-duration”和“-z none”标志可以让我创建一个在 Android 3.0->4.2 上工作的视频

Gingerbread - 我无法让 Android 2.3 开箱即用地与 HLS 一起工作,但我确实发现使用 Vitamio 库效果很好(有关更多信息,请参阅此问题)

于 2013-06-14T14:19:36.287 回答
3

某些版本的 Android 似乎将http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8上的 HLS 解释为实时 HLS 而不是 VOD HLS,因此媒体播放器开始接近“实时”点,接近内容结束,大约 29 分钟进入内容。

原因如下:在 4.3 之前,不会解析 HLS 播放列表文件中的最后一行,除非它以 '\n' 结尾。

查看该文件的更改历史记录:http ://androidxref.com/4.3_r2.1/history/frameworks/av/media/libstagefright/httplive/M3UParser.cpp ,在 12/31/12,有已修复的更改问题。这个问题在4.4上消失了。

因此,解决旧版本问题的一种方法是在服务器上播放列表的最后一行之后添加换行符,或者在您的应用程序中实现一个 HTTP 代理来有效地添加该换行符,这可能不是微不足道的......

于 2013-11-18T18:11:45.930 回答
1

您是否尝试在 URL 中为 Player 提供启动参数?

像这样:

http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8?start=0

于 2013-05-29T10:20:05.023 回答
-1
   <?xml version="1.0" encoding="utf-8" ?> 
    - <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
      <VideoView android:id="@+id/surface_view" android:layout_width="fill_parent" android:layout_height="300dp" android:layout_gravity="center" /> 
      <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/surface_view" android:layout_marginRight="62dp" android:layout_marginTop="16dp" android:text="Stop" /> 
      <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button1" android:layout_alignBottom="@+id/button1" android:layout_alignParentLeft="true" android:layout_marginLeft="34dp" android:text="Start" /> 
      </RelativeLayout>

*******************************************************************
     startB.setOnClickListener(new View.OnClickListener() {
@Override
            public void onClick(View v) {
                 mVideoView = (VideoView) findViewById(R.id.surface_view);
                   mVideoView.setVideoURI(Uri.parse("http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"));                
                   mVideoView.setMediaController(new     MediaController(MainActivity.this));
                   mVideoView.requestFocus();              
                   mVideoView.postInvalidateDelayed(100);  
                  new Thread(new Runnable() {
                      public void run() {
                          mVideoView.start();

                      }
                  }).start();
            }
        });
于 2013-06-05T13:49:44.897 回答