Android Studio 直播弹幕

我只是搬运:https://blog.csdn.net/HighForehead/article/details/55520199

写的很好很详细,挺有参考价值的

demo直通车:https://download.csdn.net/download/highforehead/9757126

直播和看视频中越来越火的控件---弹幕(Danmaku)

本文即介绍怎样实现简单的弹幕效果:咱们使用的是哔哩哔哩开源的弹幕效果库 DanmakuFlameMaster( github地址:https://github.com/Bilibili/DanmakuFlameMaster).

必需:首先咱们在项目主工程app/build.gradle中的dependencies闭包中添加如下依赖:

compile ‘com.github.ctiao:DanmakuFlameMaster:0.5.3‘

这样我们就将DanmakuFlameMaster库引入到当前项目中了.
开始展示Demo的代码给大家:

首先看咱们的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">

<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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="发送" />
</LinearLayout>

</RelativeLayout>
.
背景色为黑色,承载我是用的Video来播放本地或者网络视频,DanmakuView即是咱们的弹幕控件,LinearLayout内包含输入框和发送按钮.当然这些都是最普通的控件,最终的界面当然是由您来设定.

接下来看咱们的MainActivity的代码,如下:
.
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
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 AppCompatActivity {
private boolean showDanmaku;
//弹幕控件
private DanmakuView danmakuView;
//DanmakuContext 字体实例
private DanmakuContext danmakuContext;
private BaseDanmakuParser parser = new BaseDanmakuParser() {
@Override
protected IDanmakus parse() {
return new Danmakus();
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化VideoView控件
final VideoView videoView = (VideoView) findViewById(R.id.video_view);
//指定好VideoView的本地路径地址 SD卡根目录的xxx.mp4文件
videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/xxx.mp4");
//访问网络视频
//Uri uri = Uri.parse("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
//设置视频控制器
//videoView.setMediaController(new MediaController(this));
//设置视频路径
// videoView.setVideoURI(uri);
//开始播放
videoView.start();

new android.os.Handler().postDelayed(new Runnable() {
@Override
public void run() {
videoView.pause();
}
}, 0);

//初始化弹幕控件
danmakuView = (DanmakuView) findViewById(R.id.danmaku_view);
//默认为true 在模拟器上运行有问题
danmakuView.enableDanmakuDrawingCache(true);
//看源码得知是一个接口 怎么实现还是要咱们去重写其中的方法
danmakuView.setCallback(new DrawHandler.Callback() {
@Override
public void prepared() {
//把变量置为 true
showDanmaku = true;
//开始运行弹幕控件
danmakuView.start();
//随机生成一些弹幕内容以供测试
generateSomeDanmaku();
}

@Override
public void updateTimer(DanmakuTimer timer) {

}

@Override
public void danmakuShown(BaseDanmaku danmaku) {

}

@Override
public void drawingFinished() {

}
});
//调用 DanmakuContext.create() 完成DanmakuContext的实例化.
danmakuContext = DanmakuContext.create();
danmakuView.prepare(parser, danmakuContext);
//初始化含有输入框和按钮的线性布局
final LinearLayout operationLayout = (LinearLayout) findViewById(R.id.operation_layout);
//初始化发送按钮
final Button send = (Button) findViewById(R.id.send);
//输入框输入内容
final EditText editText = (EditText) findViewById(R.id.edit_text);
//适时的让输入框显现或隐藏
danmakuView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (operationLayout.getVisibility() == View.GONE) {
operationLayout.setVisibility(View.VISIBLE);
} else {
operationLayout.setVisibility(View.GONE);
}
}
});
//发送按钮的点击事件
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String content = editText.getText().toString();
if (!TextUtils.isEmpty(content)) {
//因为是自己的内容,所以传一个true过去,方法内部会判断这个变量
addDanmaku(content, true);
//再把输入框置为空
editText.setText("");
}
}
});
//获取到窗体的顶级父类并设置状态栏的显示隐藏
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) { //显示状态栏,Activity不全屏显示
onWindowFocusChanged(true);
}
}
});
}

/**
* 向弹幕View中添加一条弹幕
*
* @param content 弹幕的具体内容
* @param withBorder 弹幕是否有边框
*/
private void addDanmaku(String content, boolean withBorder) {
//BaseDanmaku 您可以点击进入查看源码实现
// 弹幕的相关设置:弹幕优先级 颜色 时长 文本 Z轴 Y轴 阴影 描边
// 下划线 内边距 宽度 高度 存活时间 是否是直播弹幕
BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
danmaku.text = content; //文本
danmaku.padding = 5; //内边距
danmaku.textSize = sp2px(20); //字体大小
danmaku.textColor = Color.WHITE; //文本颜色
danmaku.setTime(danmakuView.getCurrentTime()); //显示时长 偏移时间
//如果是true 证明是自己的弹幕,那么就可以更改自己想要的颜色了
if (withBorder) {
danmaku.borderColor = Color.GREEN;
}
//调用底层代码 把弹幕内容添加到LinkedList<Long> mDrawTimes;
danmakuView.addDanmaku(danmaku);
}

/**
* 随机生成一些弹幕内容以供测试
*/
private void generateSomeDanmaku() {
new Thread(new Runnable() {
@Override
public void run() {
while (showDanmaku) {
int time = new Random().nextInt(300);
String content = "" + time + time;
addDanmaku(content, false);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}

/**
* sp转px的方法。
*/
public int sp2px(float spValue) {
final float fontScale = getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}

@Override//表示Activity正在停止.
protected void onPause() {
super.onPause();
//如果弹幕控件不为空 && 弹幕控件的线程还存活
if (danmakuView != null && danmakuView.isPrepared()) {
//暂停运行弹幕控件
danmakuView.pause();
}
}

@Override//表示Activity前台并可与用户交互.
protected void onResume() {
super.onResume();
if (danmakuView != null && danmakuView.isPrepared() && danmakuView.isPaused()) {
danmakuView.resume();
}
}

@Override//表示Activity即将被销毁.
protected void onDestroy() {
super.onDestroy();
//把变量置为false
showDanmaku = false;
//如果弹幕控件还存在.调用release(); 底层调用stop(),并把底层的LinkedList<Long> mDrawTimes 置为空;
if (danmakuView != null) {
danmakuView.release();
danmakuView = null;
}
}

@Override//都说这个函数才会使用户可以与应用真正开始进行交互.
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//看了底层后得知 Build.VERSION.SDK_INT == 20 ;
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
//这个标志来帮助你的应用维持一个稳定的布局.
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
//Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
//ctivity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住.
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
//ctivity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住.
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
//Activity全屏显示,且状态栏被隐藏覆盖掉.
| View.SYSTEM_UI_FLAG_FULLSCREEN
//安卓4.4 新增.
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
}

如上,在安卓设备上,一个简单的弹幕Demo就可以实现了.

原文地址:https://www.cnblogs.com/oreox/p/10742573.html

时间: 2024-08-28 14:54:02

Android Studio 直播弹幕的相关文章

Mac下载安装Android Studio教程

今天把公司闲置的一台Mac-mini重装了下系统感觉用着速度还不错,平时上班用的机器USB有些问题,所以打算用这台Mac.以往开发用Intellij Idea就够用,但是这次项目引用的jar包太多,遭遇android Multi-Dex限制,所以用了Android Studio做分包.接下来得先下载Android Studio,之前在百度动云盘里下载过,今天却找不到了,索性不找了,自己去google下载,那接下来就给大家直播一下在Mac上设置代理访问google下载安装Android Studi

(转载) Android studio如何生成aar包

Android studio如何生成aar包 标签: Android studio如何生成aaAndroid studio aarAndroid 如何生成aar包 2016-12-21 14:42 1856人阅读 评论(0) 收藏 举报  分类: Android开发(116)  在Android Studio中对一个自己库进行生成操作时将会同时生成.jar与.aar文件. 分别存储位置: *.jar:库 /build/intermediates/bundles/debug(release)/cl

Android studio 插件之 GsonFormat (自己主动生成javabean)

概述 相信大家在做开发的过程中都写过非常多的javabean ,非常多情况下 都是一个列表数据就是一个单独的javabean.假设大家自己敲的话费时费力 还非常easy敲错. 今天给大家推荐一个插件 GsonFormat  这个插件就是能够让我们直接将服务端返回的json转化为实体类.Android studio和idea都有, eclipse我没有试过. 大家能够找找有没有. 操作步骤 第一步  下载插件 下载插件的过程我前面有一篇博客已经有具体步骤 Android Studio插件之sexy

Android 如何直播RTMP流

在android上,视频/音频流直播是极少有人关注的一部分.每当我们讨论流媒体,RTMP(Real Time Messaging Protocol)是不可或缺的.RTMP是一个基本的视频/音频直播流协议,但是不幸的是Android标准的VideoView不支持RTMP的播放.因此,如果想在android上播放RTMP直播流,你必须使用支持RTMP协议的库.  库播放由 RTMP 协议传输的流媒体. Android Vitamio 库 Vitamio是一个android和ios上基于FFmpeg的

Android studio 插件之 GsonFormat (自动生成javabean)

概述 相信大家在做开发的过程中都写过很多的javabean ,很多情况下 都是一个列表数据就是一个单独的javabean,如果大家自己敲的话费时费力 还很容易敲错. 今天给大家推荐一个插件 GsonFormat  这个插件就是可以让我们直接将服务端返回的json转化为实体类,Android studio和idea都有, eclipse我没有试过.大家可以找找有没有. 操作步骤 第一步  下载插件 下载插件的过程我前面有一篇博客已经有详细步骤 Android Studio插件之sexy edito

ubuntu12.04 android studio 安装

ubuntu12.04 android studio 安装 分类: android 2014-02-17 15:57 10756人阅读 评论(0) 收藏 举报 1.下载JDK ,我下载的是jdk-7u51-linux-i586.tar.gz 我这里有jvm文件夹,直接cd过去: $ cd /usr/lib/jvm/ 拷贝下载的jdk-7u51-linux-i586.tar.gz到jvm文件夹: $ sudo cp  ~/下载/jdk-7u51-linux-i586.tar.gz /usr/lib

Android Studio 2.2 preview发布

转:http://geek.csdn.net/news/detail/74971 15小时的时差阻隔不了隔海相望的狂欢,当多地GDG(谷歌开发者社区)组织的Google I/O Extended活动如期上演,与全世界开发者一同观看I/O大会Keynote直播时,我们站在与未来最为贴近的地方. 也是一夜之间,我们迎来了许多新工具:语音助手Google Assistant.智能音箱Google Home.很会聊天的新App Allo和Duo.全新VR平台Daydream,以及系列Android版本更

Android Studio 安装及常见问题

今年放假比去年早了一些,就提前回来了.感觉挺爽,结果教研室电脑没有带回来,悲剧是导师让我维护一下以前的项目,只能屁颠屁颠的搞起呀.只能用自己的笔记本搭建android开发环境.由于前阶段听说Android Studio用着爽歪歪,于是尝试在超卡的笔记本上跑Android Studio.哇咔咔,费了九牛二虎之力终于将Android Studio玩转了.先上个图,快过年了,祝大家新年快乐! Android官网也开始推广Android Studio了,以前官网好像提供Eclipse和ADT打包下载,现

Android Studio 连接真机不识别

本人也是初学..写错的请大神多多批评指正! 不胜荣幸!! 强烈推荐使用真机测试..除非是最后关头要测试各个Android系统版本.. 本人遇到的连不上的原因有以下几种: 1  --   手机设置问题.开USB调试   方法:  手机设置 - 开发人员选项 - USB调试  - 勾选 2  --   数据线问题.  有的数据线只能用来充电,有的可以连接存储.识别方法很简单..插上机器有USB存储设备的提示的就可以用.另外数据线如果都露线皮了..就赶紧扔了.十块八块的总比你为这个破问题纠结一下午的好