首页 > 系统 > Android > 正文

SurfaceView播放视频发送弹幕并实现滚动歌词

2019-12-11 20:55:08
字体:
来源:转载
供稿:网友

本文实例为大家分享了SurfaceView播放视频发送弹幕,并实现滚动歌词,供大家参考,具体内容如下

SurfaceView使用步骤

使用SurfaceView的步骤:

  • 首先要继承SurfaceView,实现SurfaceHolder.Callback接口。
  • 重写方法:surfaceChanged:surface大小或格式发生变化时触发,在surfaceCreated调用后该函数至少会被调用一次。
  • surfaceCreated:Surface创建时触发,一般在这个函数开启绘图线程(新的线程,不要再这个线程中绘制Surface)。
  • surfaceDestroyed:销毁时触发,一般不可见时就会销毁。
  • 利用getHolder()获取SurfaceHolder对象,调用SurfaceHolder.addCallback添加回调
  • SurfaceHolder.lockCanvas 获取Canvas对象并锁定画布,调用Canvas绘图,SurfaceHolder.unlockCanvasAndPost 结束锁定画布,提交改变。

SurfaceHolder

SurfaceHolder回调自己的三个生命周期:

  • surfaceCreated(SurfaceHolder holder)创建时
  • surfaceChanged(SurfaceHolder holder, int format, int width, int height)改变时
  • surfaceDestroyed(SurfaceHolder holder)销毁时

SurfaceView播放视频并可以发送弹幕

需要准备两个SurfaceView,一个是负责播放视频,一个负责展示弹幕。弹幕是展示在视频上面的,所以我们要给展示弹幕的SurfaceView设置两个方法:
surfaceView_danmu.setZOrderOnTop(true); ――置于上方
surfaceView_danmuHolder.setFormat(PixelFormat.TRANSPARENT); ――背景透明

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {    public static final int PROGRESS = 101;  SurfaceView surfaceView,surfaceView_danmu;  SurfaceHolder surfaceHolder,surfaceView_danmuHolder;  MediaPlayer mediaPlayer = new MediaPlayer();  String path = "/sdcard/aa.mp4";  SeekBar seekBar;  Timer timer;  EditText editText;  Button button,bt_start,bt_stop;  int x = 0;  ArrayList<DanMu> list = new ArrayList<>();  Handler handler = new Handler(){    @Override    public void handleMessage(Message msg) {      super.handleMessage(msg);      if (msg.what == PROGRESS){        seekBar.setProgress((Integer) msg.obj);        mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {          @Override          public void onSeekComplete(MediaPlayer mp) {            Toast.makeText(MainActivity.this, "播放完毕!", Toast.LENGTH_SHORT).show();          }        });      }    }  };  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    surfaceView = findViewById(R.id.sufaceview);    surfaceView_danmu = findViewById(R.id.sufaceview_danmu);    editText = findViewById(R.id.et);    button = findViewById(R.id.bt_send);    seekBar = findViewById(R.id.bar);    bt_start = findViewById(R.id.bt_start);    bt_stop = findViewById(R.id.bt_stop);    surfaceHolder = surfaceView.getHolder();    surfaceHolder.addCallback(this);    surfaceView_danmuHolder = surfaceView_danmu.getHolder();    surfaceView_danmuHolder.addCallback(this);    surfaceView_danmu.setZOrderOnTop(true);    surfaceView_danmuHolder.setFormat(PixelFormat.TRANSPARENT);    if (mediaPlayer!=null) {      try {        mediaPlayer.setDataSource(path);        mediaPlayer.prepareAsync();        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {          @Override          public void onPrepared(MediaPlayer mp) {            mediaPlayer.start();            int duration = mediaPlayer.getDuration();            seekBar.setMax(duration);            timer = new Timer();            timer.schedule(new TimerTask() {              @Override              public void run() {                int currentPosition = mediaPlayer.getCurrentPosition();                Message message = Message.obtain();                message.what = PROGRESS;                message.obj = currentPosition;                handler.sendMessage(message);              }            },0,1000);          }        });        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {          @Override          public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {          }          @Override          public void onStartTrackingTouch(SeekBar seekBar) {          }          @Override          public void onStopTrackingTouch(SeekBar seekBar) {            int progress = seekBar.getProgress();            mediaPlayer.seekTo(progress);          }        });      } catch (IOException e) {        e.printStackTrace();      }    }        button.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        String s = editText.getText().toString();        int y= (int) (Math.random()*300);        list.add(new DanMu(0,y,s,Color.RED));      }    });    bt_start.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        mediaPlayer.start();      }    });    bt_stop.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        mediaPlayer.pause();      }    });  }  @Override  public void surfaceCreated(SurfaceHolder holder) {    if (holder == surfaceHolder) {      mediaPlayer.setDisplay(holder);    }else if (holder == surfaceView_danmuHolder) {      new MyDanMuThread().start();    }  }  @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  }  @Override  public void surfaceDestroyed(SurfaceHolder holder) {  }  class MyDanMuThread extends Thread {    @Override    public void run() {      super.run();      Paint paint = new Paint();      paint.setColor(Color.RED);      paint.setTextSize(40);      while (true) {        try {          Thread.sleep(200);        } catch (InterruptedException e) {          e.printStackTrace();        }        Canvas canvas = surfaceView_danmuHolder.lockCanvas();        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);        for (int i=0;i<list.size();i++) {          DanMu danMu = list.get(i);          x = danMu.getX();          danMu.setX(x+=10);          canvas.drawText(danMu.getText(),danMu.getX(),danMu.getY(),paint);        }        surfaceView_danmuHolder.unlockCanvasAndPost(canvas);      }    }  }}

实现滚动歌词

要准备一个装有时间和歌词的集合,准备一个Timer计时器和一个该展示第几个歌词。每隔一秒去拿该歌词的下一个歌词时间与进度匹配,如果进度>=该时间,那么就画该歌词在SurfaceView上;<则不画该歌词

一定要写SD卡读写权限!!!!!

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{  SurfaceView surfaceView;  SurfaceHolder surfaceHolder;  MediaPlayer mediaPlayer = new MediaPlayer();  ArrayList<Music> list=new ArrayList<>();  Timer timer;  int count = 0;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    surfaceView = findViewById(R.id.sv);    surfaceHolder=surfaceView.getHolder();    surfaceHolder.addCallback(this);    timer = new Timer();    timer.schedule(new TimerTask() {      @Override      public void run() {        int currentPosition = mediaPlayer.getCurrentPosition();        if(list.size()>0){          if(currentPosition>=list.get(count+1).getTime()){            count++;          }        }      }    },0,500);    try {      mediaPlayer.setDataSource("/sdcard/凤凰传奇 - 最炫民族风(Live).mp3");      mediaPlayer.prepareAsync();      mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {        @Override        public void onPrepared(MediaPlayer mp) {          mediaPlayer.start();        }      });    } catch (IOException e) {      e.printStackTrace();    }    try {      StringBuffer stringBuffer = new StringBuffer();      FileInputStream fileInputStream = new FileInputStream("/sdcard/最炫民族风");      byte[] bytes = new byte[1024];      int len = 0;      while ((len=fileInputStream.read(bytes))!=-1) {        stringBuffer.append(new String(bytes,0,len));      }      Gson gson = new Gson();      JavaBean javaBean = gson.fromJson(stringBuffer.toString(), JavaBean.class);      JavaBean.LrcBean lrc = javaBean.getLrc();      String lyric = lrc.getLyric();      String[] split = lyric.split("/n");      for(int i=0;i<split.length;i++){        String trim = split[i].trim();        String[] split1 = trim.split("]");        if(split.length>=2){          String s = split1[0];          String substring1 = s.substring(1, 3);          String substring2 = s.substring(4, 6);          String substring3 = s.substring(7, 10);          long start = Integer.parseInt(substring1)*60*1000+Integer.parseInt(substring2)*1000+Integer.parseInt(substring3);          String text = split1[1];          list.add(new Music(text,start));        }      }    } catch (FileNotFoundException e) {      e.printStackTrace();    } catch (IOException e) {      e.printStackTrace();    }  }  @Override  public void surfaceCreated(SurfaceHolder holder) {    new MyThread().start();  }  @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  }  @Override  public void surfaceDestroyed(SurfaceHolder holder) {  }  class MyThread extends Thread {    @Override    public void run() {      super.run();      Paint paint = new Paint();      paint.setColor(Color.RED);      paint.setTextSize(50);      while (true){        try {          Thread.sleep(100);        } catch (InterruptedException e) {          e.printStackTrace();        }        Canvas canvas = surfaceHolder.lockCanvas();        if(canvas==null){          break;        }        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);        if(list.size()>0){          canvas.drawText(list.get(count).getTitle(),100,100,paint);        }        surfaceHolder.unlockCanvasAndPost(canvas);      }    }  }}

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表