您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么使用SurfaceView播放視頻發(fā)送彈幕,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
SurfaceView使用步驟
使用SurfaceView的步驟:
首先要繼承SurfaceView,實(shí)現(xiàn)SurfaceHolder.Callback接口。
重寫方法:surfaceChanged:surface大小或格式發(fā)生變化時(shí)觸發(fā),在surfaceCreated調(diào)用后該函數(shù)至少會(huì)被調(diào)用一次。
surfaceCreated:Surface創(chuàng)建時(shí)觸發(fā),一般在這個(gè)函數(shù)開啟繪圖線程(新的線程,不要再這個(gè)線程中繪制Surface)。
surfaceDestroyed:銷毀時(shí)觸發(fā),一般不可見時(shí)就會(huì)銷毀。
利用getHolder()獲取SurfaceHolder對(duì)象,調(diào)用SurfaceHolder.addCallback添加回調(diào)
SurfaceHolder.lockCanvas 獲取Canvas對(duì)象并鎖定畫布,調(diào)用Canvas繪圖,SurfaceHolder.unlockCanvasAndPost 結(jié)束鎖定畫布,提交改變。
SurfaceHolder
SurfaceHolder回調(diào)自己的三個(gè)生命周期:
surfaceCreated(SurfaceHolder holder)創(chuàng)建時(shí)
surfaceChanged(SurfaceHolder holder, int format, int width, int height)改變時(shí)
surfaceDestroyed(SurfaceHolder holder)銷毀時(shí)
SurfaceView播放視頻并可以發(fā)送彈幕
需要準(zhǔn)備兩個(gè)SurfaceView,一個(gè)是負(fù)責(zé)播放視頻,一個(gè)負(fù)責(zé)展示彈幕。彈幕是展示在視頻上面的,所以我們要給展示彈幕的SurfaceView設(shè)置兩個(gè)方法:
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); } } } }
實(shí)現(xiàn)滾動(dòng)歌詞
要準(zhǔn)備一個(gè)裝有時(shí)間和歌詞的集合,準(zhǔn)備一個(gè)Timer計(jì)時(shí)器和一個(gè)該展示第幾個(gè)歌詞。每隔一秒去拿該歌詞的下一個(gè)歌詞時(shí)間與進(jìn)度匹配,如果進(jìn)度>=該時(shí)間,那么就畫該歌詞在SurfaceView上;<則不畫該歌詞
一定要寫SD卡讀寫權(quán)限?。。。。?/strong>
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/鳳凰傳奇 - 最炫民族風(fēng)(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/最炫民族風(fēng)"); 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); } } } }
上述內(nèi)容就是怎么使用SurfaceView播放視頻發(fā)送彈幕,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。