最近项目要用到这个功能,网上也没查到比较好的实现方法,索性就自己写了个简单的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));
}
}
}
}
}
}
本文介绍如何在Android项目中实现MediaPlayer与字幕的同步。通过读取字幕文件,解析时间信息,并使用线程不断刷新显示当前时间的字幕内容。详细代码示例展示了如何操作MediaPlayer和处理字幕更新。
1201

被折叠的 条评论
为什么被折叠?



