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); } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。