MediaPlayer 字幕同步

本文介绍如何在Android项目中实现MediaPlayer与字幕的同步。通过读取字幕文件,解析时间信息,并使用线程不断刷新显示当前时间的字幕内容。详细代码示例展示了如何操作MediaPlayer和处理字幕更新。

最近项目要用到这个功能,网上也没查到比较好的实现方法,索性就自己写了个简单的Demo


字幕文件在Assets文件中,音频在raw文件中,首先简析字幕文件,把时间和内容分别放在两个List中,然后通过线程不断刷新字幕:


代码如下:

package com.example.vediotext;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.regex.Pattern;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import android.app.Activity;


public class MainActivity extends Activity {


private MediaPlayer mediaPlayer;
private TextView nameStr;//字幕
private ArrayList<String> subtitlesList;//存放字幕
private ArrayList subtitlestime=new ArrayList();//存放字幕对应的时间
private ImageHandler handler = new ImageHandler();
private VedioThread vThread = null;//刷新线程


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
subtitlesList=new ArrayList<String>();
nameStr = (TextView) findViewById(R.id.nameStr);
readsrt();

nameStr.setText(subtitlesList.get(0));
mediaPlayer = MediaPlayer.create(this, R.raw.u3);
mediaPlayer.start();
startVilThread();




}

public void startVilThread() {
if (vThread == null || !vThread.isAlive()) {
vThread = new VedioThread();
vThread.start();
}
}


public void stopVilThread() {
if (vThread != null) {
vThread.interrupt();
}
}
private class VedioThread extends Thread {
private boolean isVedioStop = false;


public void startVedioThread() {
isVedioStop = false;
}


public void stopVedioThread() {
isVedioStop = true;
}


@Override
public void interrupt() {
// TODO Auto-generated method stub
if (!isVedioStop) {
stopVedioThread();
}
super.interrupt();
}


@Override
public synchronized void start() {
// TODO Auto-generated method stub
startVedioThread();
super.start();
}


@Override
public void run() {
// TODO Auto-generated method stub
while (!isVedioStop) {
try {
if (mediaPlayer != null) {
int currentTime = mediaPlayer.getCurrentPosition();
Log.e("current", currentTime + "");


sleep(500);
Message msg = handler.obtainMessage();
msg.what = 0;
msg.obj = currentTime;
handler.sendMessage(msg);


}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
super.run();
}


}



//解析字幕文件
public void readsrt() {
String line = "";
int i=1;
String regex="\\d\\d:\\d\\d:\\d\\d,\\d\\d\\d --> \\d\\d:\\d\\d:\\d\\d,\\d\\d\\d";//通过正则表达式来解析时间
try {
InputStreamReader inputReader;
inputReader = new InputStreamReader(getResources().getAssets()
.open("u3.txt"));
BufferedReader bufReader = new BufferedReader(inputReader);


while ((line = bufReader.readLine()) != null){
if(i%4==3){
subtitlesList.add(line);//通过行来读取字幕内容
}
if(Pattern.matches(regex, line)){
int times;  
               int second=Integer.parseInt(line.substring(6,8));  
               int minute=Integer.parseInt(line.substring(3,5));  
               int hour=Integer.parseInt(line.substring(0,2));  
               times=second + minute*60 + hour*3600; 
               subtitlestime.add(times);//只存放字幕的开始时间,因为结束时间与第二行的开始时间相同
               Log.e("time1", subtitlestime.get(0)+"");
               if((Integer)subtitlestime.get(0)>0){
                Log.e("time2", 0+"");
               }
}
i++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}



private class ImageHandler extends Handler {


@Override
public void handleMessage(Message msg){
if (msg.what == 0) {
int time = (Integer) msg.obj;
Log.e("time3", time/1000+"");
Log.e("time4", subtitlestime.size()+"");
Log.e("time5", subtitlesList.size()+"");
//通过循环来刷新字幕
for(int i=0;i<subtitlestime.size();i++){
if(i<subtitlestime.size()-1&&time/1000>=(Integer)subtitlestime.get(i)&&
time/1000<(Integer)subtitlestime.get(i+1)){
nameStr.setText(subtitlesList.get(i));
Log.e("time6", subtitlesList.get(0));
}

else if(time/1000+1>=(Integer)subtitlestime.get(subtitlestime.size()-1)){
nameStr.setText(subtitlesList.get(subtitlesList.size()-1));
}
}
}

}
}


}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值