当前位置: 移动技术网 > 移动技术>移动开发>Android > 使用SurfaceView实现视频弹幕

使用SurfaceView实现视频弹幕

2020年03月09日  | 移动技术网移动技术  | 我要评论
本文实例为大家分享了surfaceview视频弹幕展示的具体代码,供大家参考,具体内容如下 全部代码如下: package com.example.app2; imp

本文实例为大家分享了surfaceview视频弹幕展示的具体代码,供大家参考,具体内容如下

全部代码如下:

package com.example.app2;

import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.pixelformat;
import android.graphics.porterduff;
import android.media.mediaplayer;
import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.text.textutils;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.widget.edittext;
import android.widget.toast;

import java.io.ioexception;
import java.util.arraylist;
import java.util.list;

public class mainactivity extends appcompatactivity implements surfaceholder.callback {
  private surfaceview msvvideo;
  private surfaceview msvdanmu;
  private edittext med;

  private mediaplayer mediaplayer;
  private surfaceholder svvideoholder, svdanmuholder;

  private boolean isplay = true;
  list<danmubean> list = new arraylist<>();

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    // 创建mediaplayer
    initplayer();

    // 初始化视图
    initview();
  }

  private void initplayer() {
    if (mediaplayer == null) {
      mediaplayer = new mediaplayer();
    }
    // 重置
    mediaplayer.reset();

    try {
      mediaplayer.setdatasource("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
      mediaplayer.prepareasync(); //异步准备
      mediaplayer.setonpreparedlistener(new mediaplayer.onpreparedlistener() {
        @override
        public void onprepared(mediaplayer mp) {
          mediaplayer.setlooping(true); //是否开启循环播放
          mediaplayer.start(); //开始播放
        }
      });
    } catch (ioexception e) {
      e.printstacktrace();
    }
  }

  /**
   * 发送的信息
   *
   * @param view
   */
  public void send(view view) {
    submit();
  }

  private void submit() {
    // validate 非空判断
    string edstring = med.gettext().tostring().trim();
    if (textutils.isempty(edstring)) {
      toast.maketext(this, "edstring不能为空", toast.length_short).show();
      return;
    }

    list.add(new danmubean(edstring)); //添加数据
    med.settext(""); //清空
  }

  private void initview() {
    msvvideo = (surfaceview) findviewbyid(r.id.sv_video);
    msvdanmu = (surfaceview) findviewbyid(r.id.sv_danmu);
    med = (edittext) findviewbyid(r.id.ed);

    // 初始化 svdanmuholder svvideoholder
    svvideoholder = msvvideo.getholder();
    svdanmuholder = msvdanmu.getholder();

    // 添加监听
    svvideoholder.addcallback(this);
    svdanmuholder.addcallback(this);

    // 将弹幕显示在最上层, 并设置为透明
    msvdanmu.setzorderontop(true);
    svdanmuholder.setformat(pixelformat.transparent); //pixelformat: 像素格式, transparent(2):透明的; translucent(-3):半透明
  }

  /**
   * surfacecreated:创建
   *
   * @param holder
   */
  @override
  public void surfacecreated(surfaceholder holder) {
    if (holder == svvideoholder) {
      mediaplayer.setdisplay(svvideoholder); //将内容显示在 svvideoholder上
    } else if (holder == svdanmuholder) {
      // 弹幕设置 开启线程
      new thread(new runnable() {
        @override
        public void run() {
          while (isplay) { //死循环
            // 得到画笔, 设置属性
            paint paint = new paint();
            paint.setstrokewidth(5); //设置笔画宽度
            paint.settextsize(30); //设置字体大小
            paint.setcolor(color.green); // 设置颜色

            // 得到画布 通过lockcanvas
            canvas canvas = svdanmuholder.lockcanvas();
            if (canvas == null) {
              break;
            }

            // 填充画布的颜色
            canvas.drawcolor(pixelformat.transparent, porterduff.mode.clear); //参数1: 设为透明, 参2: porterduff.mode.clear: 所绘制不会提交到画布上

            // 设置弹幕内容
            for (int i = 0; i < list.size(); i++) {
              string text = list.get(i).text;
              canvas.drawtext(text, list.get(i).x += 1, list.get(i).y, paint);

              if (list.get(i).x > msvvideo.getwidth()) {
                list.get(i).x = 0;
              }
            }

            // 提交
            svdanmuholder.unlockcanvasandpost(canvas);
          }
        }
      }).start();
    }
  }

  @override
  public void surfacechanged(surfaceholder holder, int format, int width, int height) {

  }

  @override
  public void surfacedestroyed(surfaceholder holder) {
    isplay = false;
  }
}

布局xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout 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:orientation="vertical"
  tools:context=".mainactivity">

  <framelayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <surfaceview
      android:id="@+id/sv_video"
      android:layout_width="match_parent"
      android:layout_height="280dp" />

    <surfaceview
      android:id="@+id/sv_danmu"
      android:layout_width="match_parent"
      android:layout_height="280dp" />
  </framelayout>

  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <edittext
      android:id="@+id/ed"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1" />

    <button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:onclick="send"
      android:text="弹幕" />

  </linearlayout>
</linearlayout>

效果界面:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网