您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么使用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); } } } }
上述內容就是怎么使用SurfaceView播放視頻發送彈幕,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。