Using surfaceview to realize video barrage

This example shares the specific code of surfaceview video barrage display for your reference. The specific contents are as follows

All codes are as follows:

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;
  }
}

Layout 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>

Effect interface:

The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>