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(SurfaceHolderholder)创建时
- surfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight)改变时
- surfaceDestroyed(SurfaceHolderholder)销毁时
SurfaceView播放视频并可以发送弹幕
需要准备两个SurfaceView,一个是负责播放视频,一个负责展示弹幕。弹幕是展示在视频上面的,所以我们要给展示弹幕的SurfaceView设置两个方法:
surfaceView_danmu.setZOrderOnTop(true);——置于上方
surfaceView_danmuHolder.setFormat(PixelFormat.TRANSPARENT);——背景透明
publicclassMainActivityextendsAppCompatActivityimplementsSurfaceHolder.Callback{ publicstaticfinalintPROGRESS=101; SurfaceViewsurfaceView,surfaceView_danmu; SurfaceHoldersurfaceHolder,surfaceView_danmuHolder; MediaPlayermediaPlayer=newMediaPlayer(); Stringpath="/sdcard/aa.mp4"; SeekBarseekBar; Timertimer; EditTexteditText; Buttonbutton,bt_start,bt_stop; intx=0; ArrayListlist=newArrayList<>(); Handlerhandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ super.handleMessage(msg); if(msg.what==PROGRESS){ seekBar.setProgress((Integer)msg.obj); mediaPlayer.setOnSeekCompleteListener(newMediaPlayer.OnSeekCompleteListener(){ @Override publicvoidonSeekComplete(MediaPlayermp){ Toast.makeText(MainActivity.this,"播放完毕!",Toast.LENGTH_SHORT).show(); } }); } } }; @Override protectedvoidonCreate(BundlesavedInstanceState){ 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(newMediaPlayer.OnPreparedListener(){ @Override publicvoidonPrepared(MediaPlayermp){ mediaPlayer.start(); intduration=mediaPlayer.getDuration(); seekBar.setMax(duration); timer=newTimer(); timer.schedule(newTimerTask(){ @Override publicvoidrun(){ intcurrentPosition=mediaPlayer.getCurrentPosition(); Messagemessage=Message.obtain(); message.what=PROGRESS; message.obj=currentPosition; handler.sendMessage(message); } },0,1000); } }); seekBar.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener(){ @Override publicvoidonProgressChanged(SeekBarseekBar,intprogress,booleanfromUser){ } @Override publicvoidonStartTrackingTouch(SeekBarseekBar){ } @Override publicvoidonStopTrackingTouch(SeekBarseekBar){ intprogress=seekBar.getProgress(); mediaPlayer.seekTo(progress); } }); }catch(IOExceptione){ e.printStackTrace(); } } button.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ Strings=editText.getText().toString(); inty=(int)(Math.random()*300); list.add(newDanMu(0,y,s,Color.RED)); } }); bt_start.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ mediaPlayer.start(); } }); bt_stop.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ mediaPlayer.pause(); } }); } @Override publicvoidsurfaceCreated(SurfaceHolderholder){ if(holder==surfaceHolder){ mediaPlayer.setDisplay(holder); }elseif(holder==surfaceView_danmuHolder){ newMyDanMuThread().start(); } } @Override publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){ } @Override publicvoidsurfaceDestroyed(SurfaceHolderholder){ } classMyDanMuThreadextendsThread{ @Override publicvoidrun(){ super.run(); Paintpaint=newPaint(); paint.setColor(Color.RED); paint.setTextSize(40); while(true){ try{ Thread.sleep(200); }catch(InterruptedExceptione){ e.printStackTrace(); } Canvascanvas=surfaceView_danmuHolder.lockCanvas(); canvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR); for(inti=0;i 实现滚动歌词
要准备一个装有时间和歌词的集合,准备一个Timer计时器和一个该展示第几个歌词。每隔一秒去拿该歌词的下一个歌词时间与进度匹配,如果进度>=该时间,那么就画该歌词在SurfaceView上;<则不画该歌词
一定要写SD卡读写权限!!!!!
publicclassMainActivityextendsAppCompatActivityimplementsSurfaceHolder.Callback{ SurfaceViewsurfaceView; SurfaceHoldersurfaceHolder; MediaPlayermediaPlayer=newMediaPlayer(); ArrayListlist=newArrayList<>(); Timertimer; intcount=0; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); surfaceView=findViewById(R.id.sv); surfaceHolder=surfaceView.getHolder(); surfaceHolder.addCallback(this); timer=newTimer(); timer.schedule(newTimerTask(){ @Override publicvoidrun(){ intcurrentPosition=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(newMediaPlayer.OnPreparedListener(){ @Override publicvoidonPrepared(MediaPlayermp){ mediaPlayer.start(); } }); }catch(IOExceptione){ e.printStackTrace(); } try{ StringBufferstringBuffer=newStringBuffer(); FileInputStreamfileInputStream=newFileInputStream("/sdcard/最炫民族风"); byte[]bytes=newbyte[1024]; intlen=0; while((len=fileInputStream.read(bytes))!=-1){ stringBuffer.append(newString(bytes,0,len)); } Gsongson=newGson(); JavaBeanjavaBean=gson.fromJson(stringBuffer.toString(),JavaBean.class); JavaBean.LrcBeanlrc=javaBean.getLrc(); Stringlyric=lrc.getLyric(); String[]split=lyric.split("\n"); for(inti=0;i =2){ Strings=split1[0]; Stringsubstring1=s.substring(1,3); Stringsubstring2=s.substring(4,6); Stringsubstring3=s.substring(7,10); longstart=Integer.parseInt(substring1)*60*1000+Integer.parseInt(substring2)*1000+Integer.parseInt(substring3); Stringtext=split1[1]; list.add(newMusic(text,start)); } } }catch(FileNotFoundExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); } } @Override publicvoidsurfaceCreated(SurfaceHolderholder){ newMyThread().start(); } @Override publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){ } @Override publicvoidsurfaceDestroyed(SurfaceHolderholder){ } classMyThreadextendsThread{ @Override publicvoidrun(){ super.run(); Paintpaint=newPaint(); paint.setColor(Color.RED); paint.setTextSize(50); while(true){ try{ Thread.sleep(100); }catch(InterruptedExceptione){ e.printStackTrace(); } Canvascanvas=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); } } } } 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。