SurfaceView播放視頻發(fā)送彈幕并實現(xiàn)滾動歌詞
本文實例為大家分享了SurfaceView播放視頻發(fā)送彈幕,并實現(xiàn)滾動歌詞,供大家參考,具體內(nèi)容如下
SurfaceView使用步驟
使用SurfaceView的步驟:
- 首先要繼承SurfaceView,實現(xiàn)SurfaceHolder.Callback接口。
- 重寫方法:surfaceChanged:surface大小或格式發(fā)生變化時觸發(fā),在surfaceCreated調(diào)用后該函數(shù)至少會被調(diào)用一次。
- surfaceCreated:Surface創(chuàng)建時觸發(fā),一般在這個函數(shù)開啟繪圖線程(新的線程,不要再這個線程中繪制Surface)。
- surfaceDestroyed:銷毀時觸發(fā),一般不可見時就會銷毀。
- 利用getHolder()獲取SurfaceHolder對象,調(diào)用SurfaceHolder.addCallback添加回調(diào)
- SurfaceHolder.lockCanvas 獲取Canvas對象并鎖定畫布,調(diào)用Canvas繪圖,SurfaceHolder.unlockCanvasAndPost 結(jié)束鎖定畫布,提交改變。
SurfaceHolder
SurfaceHolder回調(diào)自己的三個生命周期:
- surfaceCreated(SurfaceHolder holder)創(chuàng)建時
- surfaceChanged(SurfaceHolder holder, int format, int width, int height)改變時
- surfaceDestroyed(SurfaceHolder holder)銷毀時
SurfaceView播放視頻并可以發(fā)送彈幕
需要準備兩個SurfaceView,一個是負責播放視頻,一個負責展示彈幕。彈幕是展示在視頻上面的,所以我們要給展示彈幕的SurfaceView設(shè)置兩個方法:
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);
}
}
}
}
實現(xiàn)滾動歌詞
要準備一個裝有時間和歌詞的集合,準備一個Timer計時器和一個該展示第幾個歌詞。每隔一秒去拿該歌詞的下一個歌詞時間與進度匹配,如果進度>=該時間,那么就畫該歌詞在SurfaceView上;<則不畫該歌詞
一定要寫SD卡讀寫權(quán)限?。。。?!
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);
}
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持我們。
上一篇:Android WebView實現(xiàn)頂部進度條
欄 目:Android
本文標題:SurfaceView播放視頻發(fā)送彈幕并實現(xiàn)滾動歌詞
本文地址:http://www.jygsgssxh.com/a1/Android/9041.html
您可能感興趣的文章
- 01-10Android MediaPlayer 播放音頻的方式
- 01-10Android使用MediaPlayer和TextureView實現(xiàn)視頻無縫切換
- 01-10Android MediaPlayer 音頻倍速播放 調(diào)整播放速度問題
- 01-10Android使用MediaCodec將攝像頭采集的視頻編碼為h264
- 01-10兩個surfaceView實現(xiàn)切換效果
- 01-10Android基于騰訊云實時音視頻仿微信視頻通話最小化懸浮
- 01-10Android采用消息推送實現(xiàn)類似微信視頻接聽
- 01-10android使用surfaceview+MediaPlayer播放視頻
- 01-10Android實現(xiàn)視頻彈幕功能
- 01-10Android使用SoundPool實現(xiàn)播放音效


閱讀排行
本欄相關(guān)
- 01-10Android自定義View之繪制圓形頭像功能
- 01-10Android實現(xiàn)雙擊返回鍵退出應用實現(xiàn)方
- 01-10android實現(xiàn)簡單計算器功能
- 01-10android實現(xiàn)記住用戶名和密碼以及自動
- 01-10C++自定義API函數(shù)實現(xiàn)大數(shù)相乘算法
- 01-10Android 友盟第三方登錄與分享的實現(xiàn)代
- 01-10android實現(xiàn)指紋識別功能
- 01-10如何給Flutter界面切換實現(xiàn)點特效
- 01-10Android實現(xiàn)圓形漸變加載進度條
- 01-10Emoji表情在Android JNI中的兼容性問題詳
隨機閱讀
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結(jié)
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個骰子


