使用VLC-Android写一个简单的电视直播demo
近两年每天各种新的“干货”出来,可以说真的是百花齐放百家争鸣,每天也有各种各样不同的文章在简书和各大平台上崭露头角。而我就比较吃亏了,写文章容易词穷,文字功底一般,对于技术性的文字,也就记录记录流水账,再加上我本来就没有什么技术功底和学术功底,写不出什么干货文来,所以距离上一次写博客文章已经过去很久很久以前的事情了。

前一阵子我买了一个电视盒子,所以我想写个电视应用,没事可以在盒子上安装自己可控的电视应用,自己维护电视频道,所以我开始着手做这件事情。

所以本文就是我就随手记录一下开发的思考过程,本文是最简单的入门文,大牛们可以绕开此文。

准备工作
首先其一,要想一下如何做一个简单的直播播放器的demo.

我们考虑一下,做一个电视直播应用需要哪些需求。
1、有好多台
2、能看直播频道
3、能装到盒子上

详细一点的需求
再详细一点说就是:
1、能维护一个电视频道列表
2、能够播放直播的流媒体视频,并且能够兼容多种流媒体视频协议和视频封装和编码格式
3、能安装到多种硬件平台的Android盒子上

技术要求和实现
我们可以看到,这玩意儿的业务逻辑实在是再简单不过了,只是个demo嘛。
首先看第一个,一个列表,相当简单,维护一个ListView,并且用一个数据表来缓存这个列表,就OK了,毫无干货。
先跳过第二个,看第三个,因为第二个看起来好麻烦的样子。
第三个,我感觉这些便宜的盒子大多数是armv7a的硬件平台,最低系统版本是4.4,所以我们的应用只要考虑在这上面能够播放视频流就可以了。

回过头来看最主要的要求,首先,我们要支持的是视频格式。现在大多数硬件平台应该是可以轻松支持H.264,1080P,30fps的视频解码,包括硬件解码和软件解码,而现在的流媒体视频大多数是这种方式编码传输,当然,不排除使用MPEG2格式的视频。不管是硬件解码还是软件解码,只要能解码,就是好码。嗯。
前面说啰嗦了,简言之,只要是流媒体视频,我们只要考虑能够支持以下编码即可:
H.264, MPEG2, ,稍微好点的可以支持H.265。
支持的分辨率大小,我想现在没有不支持1080P的吧,那么1080P以下应该是没有问题的。
帧率要达到30fps就不用说了。

另外,上面说的只是视频编码格式。还没有提到流传输协议。我们最常见的有三种:
rtsp, hls, rtmp. Android系统的多媒体框架本身已经对除了rtmp以外的流媒体协议和视频格式都已经有所支持,但是问题在于支持的程度根据硬件平台不同行为可能有些许不同。所以在继续下去之前,我希望能够保证这三种协议都能够被我的demo所支持,因为rtmp协议的视频流并不在少数。所以,我并不计划使用系统本身的媒体框架来做。我选用ijkplayer或者vlc来使用。

对比ijkplayer和vlc,两个都是在ffmpeg基础上进行开发的媒体框架,各自有各自的长处。我在测试时更加推荐ijkplayer,因为它的性能表现和软硬解码的切换的灵活性十分好,并且支持SurfaceView, TextureView可更换渲染视频,并且可以选择使用OpenGLES渲染视频。ijkplayer解析和使用已有很多文章说明,其本质是SDL配合FFMPEG渲染解码。但是昨天发生了一件以外情况,对于我想要快速原型的愿望有所顾虑。ijkplayer在乐视2手机上报了一个(-10000,0)错误,官方issue中也有很多相同问题的人,但是并没有解决这个问题。因此只好更换了VLC-android来构建这个demo。

老实说,我在Ubuntu下移植构建ffmpeg和vlc都遇到过很多麻烦,走过很多弯路。但是我希望能够快速实现我的目的,所以我还是找到了别人提前编译好的依赖包来使用,我只拿api来使用。当然我在使用vlc-android期间也走了一点弯路,被所谓的MediaPlayer-like API思维禁锢的我各种报错运行不成功,结果我不撞南墙不回头,索性绕开这个坑,找了使用范例来写。

首先我建了一个android项目,并且在build.gradle文件当中加入已经编译好的依赖。这个依赖来自于:
https://github.com/mrmaffen/vlc-android-sdk,根据上面的说明,加入

dependencies {
compile “de.mrmaffen:vlc-android-sdk:2.0.6”

readme当中依然提到了如果想自己构建,如何做如何做。自己构建?有空再说。
我们可以直接开始使用VLC库的API了。
以下代码我只写出关键代码,其余的多余代码为了不干扰实现,不贴出来。

首先,我们要有一个SurfaceView表面来显示渲染内容:

<SurfaceView
android:id=”@+id/srfc”
android:layout_width=”match_parent”
android:layout_height=”210dp” /> 
然后需要两个按钮

<Button
android:id=”@+id/btn_play_sample_1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”QTV1″ />

<Button
android:id=”@+id/btn_play_sample_2″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”QTV2″
android:visibility=”visible” /> 
作为两个频道切换

实在不能再简单了,然后上我们的Java代码,在Activity中,我们需要这么使用:

//需要导入的包,不要用错包的MediaPlayer类
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;

//在Activity中可以为按钮增加事件
SurfaceView srfc;
LibVLC libVLC = null;
ArrayList<String> options = new ArrayList<>();
libVLC = new LibVLC(getApplication(), options);
try {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = new MediaPlayer(libVLC);
String url = getString(R.string.http_video11_qtv_com_cn_qtv1_sd_manifest_m3u8);

//
mediaPlayer.getVLCVout().setVideoSurface(srfc.getHolder().getSurface(), srfc.getHolder());
//播放前还要调用这个方法
mediaPlayer.getVLCVout().attachViews();

Media media = new Media(libVLC, Uri.parse(url));

mediaPlayer.setMedia(media);
mediaPlayer.play();

} catch (Exception e) {
e.printStackTrace();

并且

@Override
protected void onPause() {
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}

@Override
protected void onResume() {
super.onResume();
if (mediaPlayer != null) {
mediaPlayer.play();
}

然后就可以使用了

————————————————
版权声明:本文为CSDN博主「XellossRyan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lp8800/article/details/62221092