BiliBili

Project Url: lingxiaopua/BiliBili
Introduction: 基于 ijkplayer+rxjava+retrofit,组件化思想,实现一个仿 B 站的 Android 客户端
More: Author   ReportBugs   
Tags:

使用 ijkplayer,实现一个仿 B 站的 Android 客户端。使用组件化的思想对项目进行拆分,目前分出两个组件,一个是网络请求组件,一个是视频播放组件。

扫码体验:

组件化实现方案

组件化使用的方案出自张华洋的文章:Android 组件化方案

在 gradle.properties 中,有一个 isModule 值,为 true 时是组件化模式,为 false 为 library。在业务组件的 build.gradle 中读取 isModule,代码如下:

if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

在 AndroidStudio 中每一个组件都会有对应的 AndroidManifest.xml,application 和 library 使用的 AndroidManifest.xml 不同,所以要为组件开发模式下的业务组件再创建一个 AndroidManifest.xml,然后根据 isModule 指定 AndroidManifest.xml 的文件路径,让业务组件在集成模式和组件模式下使用不同的 AndroidManifest.xml:

sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

组件功能介绍

ijkplayer 组件(功能组件)

该组件是一个视频播放组件,在 ubuntu16.04 上集成编译了 ijkplayer,支持 rtsp 和 rtmp 的视频直播推流。提供了一个自定义 view,可以使用该 view 实现本地/网络视频的播放、暂停、快进、视频亮度、音量的调节。ijkplayer0.8.8 下载地址

使用方式如下:

声明所需权限,用于播放网络视频和本地视频:

<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

注意,如果横竖屏切换不想重新走一遍生命周期,还需要在表单中设置 Activity 的 configChanges 属性:

<activity android:name=".PlayActivity"
                  android:configChanges="orientation|keyboardHidden|screenSize" >
</activity

在布局中添加如下 view:

<com.bilibili.lingxiao.ijkplayer.widget.SimplePlayerView
            android:id="@+id/simple_view"
            android:layout_width="match_parent"
            android:layout_height="180dp">
    </com.bilibili.lingxiao.ijkplayer.widget.SimplePlayerView>

在 Activity/Fragment 中的 oncreate 方法里:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_play)
    //屏幕常亮
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    /** 普通播放 start **/
    var url = getIntent().getStringExtra("url");
    simple_view
            .setVideoUrl(url)
            .setVideoTitle("这是标题")
            .startPlay()
}
override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
        //横竖屏切换 显示/隐藏 actionbar
        var isPortrait = simple_view.onConfigurationChang(newConfig)
        if (isPortrait) {
            supportActionBar?.show()
        } else {
            supportActionBar?.hide()
        }
    }

    override fun onBackPressed() {
        simple_view.onBackPressed()
        if (!simple_view.isPortrait){
            supportActionBar?.show()
        }else{
            super.onBackPressed()
        }
    }

    override fun onPause() {
        super.onPause()
        simple_view.onPause()
    }

    override fun onResume() {
        super.onResume()
        simple_view.onResume()
    }

    override fun onDestroy() {
        super.onDestroy()
        simple_view.onDestory()
    }

common 组件(功能组件)

  1. common 组件是基础库,添加一些公用的类;
  2. 网络请求、图片加载、工具类、base 类等;
  3. 声明 APP 需要的 uses-permission;
  4. 定义 mvp 架构实现网络请求

目前完成的功能

  • 整体架构搭建
  • 对 b 站客户端抓包,分析接口
  • 主界面布局完成
  • 完成直播播放页面
  • 完成推荐视频的播放
  • 视频弹幕获取

项目截图:

直播界面 聊天界面 个人信息 popwindow 主播信息界面 粉丝榜 大航海
视频播放 视频评论 侧滑 分区 追番 webview
Support Me
Apps
About Me
Google+: Trinea trinea
GitHub: Trinea