欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

使用SurfaceView实现视频弹幕

程序员文章站 2023-02-19 14:50:21
本文实例为大家分享了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>

效果界面:

使用SurfaceView实现视频弹幕

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