简单概述
现在有个很流行视频的效果就是弹幕效果,满屏幕的文字从右到左飘来飘去。看的眼花缭乱,看起来还蛮cool的现在就是来实现这一的一个效果,大部分的都是从右向左移动漂移,本文的效果中也支持从左向右的漂移移动效果,同时也支持屏幕弹幕最多显示个数的设置。
一、为什么使用视频弹幕:
说起弹幕,想必很多朋友首先想到的不是A站AcFun就是B站bilibili,弹幕文化正是在 这两个二次元社区里发扬光大,为宅男宅女们带来了无尽的乐趣。随着视频行业的火热,不仅腾讯视频、爱奇艺、优酷这些平台型视频产品引入了弹幕功能,近来也有诸多的短视频产品逐渐在尝试这种互动方式
很多人或许在生活中比较寡言少语,但在网络中却十分地活跃,渴望得到别人的关注和认可,而弹幕正好就成了这些人刷存在感的工具。就像在直播间里土豪用刷火箭来彰显自己的身份一样,在某个视频特别是热门IP,很多忠实粉丝都会用诸如“我是第一个”、“火钳刘明”、“xx,我喜欢你”之类的语句来刷存在感。这类弹幕经常会引发一阵跟帖或调侃骂战,极大地带动了视频的观看氛围,让活跃用户有了表达自我的动力和热情。
弹幕最大的特点便是用户可针对视频某个时间点的剧情发表观点,这种针对性的评论与剧情具有强耦合性,能让观看者在当前观看点产生共鸣或引发思考。这相比一般的评论来讲,对象更明确,更容易引发回复互动。接下就简单实现这个弹幕。
二、原理解析
1.开始的思路。
(1)自定义ViewGroup-XCDanmuView,继承RelativeLayout来实现,当然也可以继承其他三大布局类。先展示一下项目布局。
(2)需要将界面设置为横屏,并对它进行一些配置。下面是清单文件的代码。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mythmayor.a1805danmudemo">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
(3)我在这里用到了哔哩哔哩开源的弹幕效果库DanmakuFlameMaster(这个库的功能也比较强大,但本篇文章中可能只用到其基本功能,有兴趣的同学可以到其GitHub上进行学习)。需要配置到build.gradle的dependencies中。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
testCompile 'junit:junit:4.12'
compile 'com.github.ctiao:DanmakuFlameMaster:0.9.25'
}
2.把控效果
在观看直播或视频的时候,我们经常能看到弹幕的效果。首先我们从布局上讲一下,其实非常简单,布局最下层是播放器视图,中间那层一般则是弹幕视图层,最上层是操作界面的视图层。这样一说大家的心里是不是就有一个很清晰的结构了。那么下面就直接上布局的代码了。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context="com.mythmayor.a1805danmudemo.MainActivity">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/danmaku_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/operation_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#fff"
android:visibility="gone">
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Send" />
</LinearLayout>
</RelativeLayout>
3.核心代码。在这里有几点是需要说明的。
(1)首先播放视频的话这里用到的是VideoView,使用起来也非常简单,先要设置一个视频文件的路径:String uri = “android.resource://” + getPackageName() + “/” + R.raw.danmu;然后调用start方法即可播放视频了。
(2)关于弹幕库的使用,可参考下面代码进行理解。我们需要创建一个DanmakuContext的实例和一个弹幕的解析器(这里直接创建了一个全局的BaseDanmakuParser),创建完成后就可以调用DanmakuView的prepare()方法了,调用这一方法后会自动调用回调函数中的prepared()方法,这个方法中调用了start方法,弹幕就此开始工作了。
package com.mythmayor.a1805danmudemo;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.VideoView;
import java.util.Random;
import master.flame.danmaku.controller.DrawHandler;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.DanmakuTimer;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.ui.widget.DanmakuView;
public class MainActivity extends Activity {
private boolean showDanmaku;
private DanmakuView danmakuView