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

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

程序员文章站 2022-05-21 21:18:00
本文实例为大家分享了surfaceview播放视频发送弹幕,并实现滚动歌词,供大家参考,具体内容如下 surfaceview使用步骤 使用surfaceview的步骤:...

本文实例为大家分享了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);
      }
    }
  }
}

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