BiliBili Android第三方——第2步

Android开发新手,若有错误请指出,谢谢~

blog
github
简书

视频播放

bilibili的核心功能不用说,即播放视频 + 弹幕功能,本章主要讲述如何在Android中播放B站视频(争取下一章中加入弹幕功能)。首先,Android中播放视频使用Bilibili官方开源的ijkMediaPlayer,Android自带的MediaPlayer支持格式有限,无法满足Bilibili视频源的格式。ijkPlayer的github中展示了许多编译、修改的内容,对于仅需要使用的可以暂时不看。

获取视频地址

视频主要分为2类,直播和点播,这两类的接口是不一样的。其中点播又有专辑、番剧等包含集数等概念的内容,需要播放不同内容。这里我们只讨论一个地址的那种,即单个视频。

  1. 直播地址
  2. 点播地址

直播地址URL如下,可以通过live/Index获取直播页的内容,其中最重要的内容为每一个直播Item的room_id,其他也有很多接口获取房间号内容,如直播详情、直播列表等,这里使用直播首页作为示例。

http://live.bilibili.com/AppIndex/home?_device=android&_hwid=51e96f5f2f54d5f9&_ulv=10000&access_key=563d6046f06289cbdcb472601ce5a761&appkey=c1b107428d337928&build=410000&platform=android&scale=xxhdpi&sign=fbdcfe141853f7e2c84c4d401f6a8758
{
    owner: {
        face: "http://i0.hdslb.com/bfs/face/ac9785955b2d95391495869e7d64b8dc7d9499d4.jpg",
        mid: 867152,
        name: "Tsubomixy"
    },
    cover: {
        src: "http://i0.hdslb.com/group1/M00/B6/AA/oYYBAFbmgraAF4DkAADqc2Inrws485.jpg",
        height: 180,
        width: 320
    },
    title: "疯狂掉分少年",
    room_id: 81414,
    online: 157
}

每一个直播间的Item如上述Json,每一个视频直播都对应一个直播间Id,与Web端相同,通过调用接口获取视频直播地址。具体playurl接口获取直播视频地址如下,返回数据为xml格式,

http://live.bilibili.com/api/playurl?player=1&quality=0&cid=room_id

房间号23058为B站官方音乐直播间,房间号稳定,可供大家测试。将http://live.bilibili.com/api/playurl?player=1&quality=0&cid=23058 粘到浏览器中即可,这种xml格式浏览器无法直接解析因此可能看不到内容,需要查看源代码,即可查看到如下图的内容:

![直播地址xml](https://github.com/HakuLess/ImageLib/blob/master/blog/live_xml.png?raw=true =744×209)

url为默认使用线路,b1、b2、b3指的是备用线路1、2、3。至此,我们获取到了B站直播的播放地址。接下来就可以使用ijkplayer使用该地址进行播放视频。

点播地址URL与直播地址相似,同样有cid的概念。首先需要通过其他接口获取视频直播地址的cid,然后通过如下接口获取点播视频的地址:

String sign_this = string2MD5("appkey=" + appkey + "&cid=" + cid + secretkey);
String url = "http://interface.bilibili.com/playurl?appkey=" + appkey + "&cid=" + cid + "&sign=" + sign_this;

视频点播与直播不一样需要使用secretkey进行md5加密,这部分详细内容可以查看第0步的内容。这里使用cid为3885454为例,其获取地址URL为 http://interface.bilibili.com/playurl?appkey=f3bb208b3d081dc8&cid=3885454&sign=3aa2879fb591b4e297ed3e69156c821e

<video>
    <result>suee</result>
    <timelength>206000</timelength>
    <format>
        <![CDATA[ flv ]]>
    </format>
    <accept_format>
        <![CDATA[ mp4,hdmp4,flv ]]>
    </accept_format>
    <accept_quality>
        <![CDATA[ 3,2,1 ]]>
    </accept_quality>
    <from>
        <![CDATA[ local ]]>
    </from>
    <seek_param>
        <![CDATA[ start ]]>
    </seek_param>
    <seek_type>
        <![CDATA[ offset ]]>
    </seek_type>
    <src>0</src>
    <durl>
        <order>1</order>
        <length>206000</length>
        <size>39674116</size>
        <url>
            <![CDATA[
http://cn-zjhz5-dx.acgvideo.com/vg11/0/28/3885454-1.flv?expires=1458561300&ssig=SalA4VKqDvz49duWpIJ1Tg&oi=1961670062&appkey=f3bb208b3d081dc8&or=3026306826&rate=0
]]>
        </url>
        <backup_url>
            <url>
                <![CDATA[
http://cn-zjwz3-dx.acgvideo.com/vg16/7/18/3885454-1.flv?expires=1458561300&ssig=OmgeF1kfdbUgTkGTBMO2xw&oi=1961670062&appkey=f3bb208b3d081dc8&or=3026306826&rate=0
]]>
            </url>
            <url>
                <![CDATA[
http://cn-zjsx10-dx.acgvideo.com/vg2/f/a0/3885454-1.flv?expires=1458561300&ssig=MTYHl-CUFarh8LpXnMXjEg&oi=1961670062&appkey=f3bb208b3d081dc8&or=3026306826&rate=0
]]>
        </url>
        </backup_url>
    </durl>
</video>```

其中三个URL分别为默认线路、备用线路1和备用线路2。至此,获取单个视频点播的视频地址~ 下面就可以使用播放器进行视频播放了~!
 
##### 播放视频

播放视频的方式不止一种,这里只提供使用ijkplayer播放视频的方式,需要的同学可以看[ijkplayer github](https://github.com/Bilibili/ijkplayer)。对于我们只使用不修改的同学,可以直接在gradle中配置即可。

required
allprojects {
repositories {
jcenter()
}
}

dependencies {
# required, enough for most devices.
compile ‘tv.danmaku.ijk.media:ijkplayer-java:0.4.5.1’
compile ‘tv.danmaku.ijk.media:ijkplayer-armv7a:0.4.5.1’

# Other ABIs: optional
compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.4.5.1'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.4.5.1'
compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.4.5.1'

# ExoPlayer as IMediaPlayer: optional, experimental
compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.4.5.1'

}

对于大部分情况只需要配置required项即可,之后就可以在项目中直接使用ijkMediaPlayer,使用方式与普通的MediaPlayer相似,具体代码如下:

private void playVideo(String uri) {
try {
ijkMediaPlayer.setDataSource(this, Uri.parse(uri));
ijkMediaPlayer.setDisplay(holder);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                ijkMediaPlayer.setDisplay(holder);
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
        ijkMediaPlayer.prepareAsync();
        ijkMediaPlayer.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
完整项目代码可以在[我的github](https://github.com/HakuLess)中查看。项目截图与bilibili官方对比图如下:
  ![直播首页截图](https://github.com/HakuLess/ImageLib/blob/master/blog/compare_live_index.png?raw=true =578x499)
 ![直播页面_官方](https://raw.githubusercontent.com/HakuLess/ImageLib/master/blog/compare_live_play_bili.jpeg?raw=true =285x577)
 ![直播页面_自定义](https://github.com/HakuLess/ImageLib/blob/master/blog/compare_live_play_hbili.jpeg?raw=true?raw=true =285x577)
 
 有待开发的功能还有很多,如弹幕、评论、视频下载等,大家敬请期待~
 
##### ThanksTo

* [bilibili视频解析](http://www.iippcc.com/bilibili/)
* [爱bilibili](http://www.ibilibili.com/)
* [B站视频地址获取](https://www.blackglory.me/bilibili-video-source-get/)
* [B站API](http://www.fuckbilibili.com/biliapi.html)
* [哔哩哔哩JJ](http://www.bilibilijj.com/)
    原文作者:HaKu
    原文地址: https://www.jianshu.com/p/3575a78046f5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞