前提摘要:

 可以给电影加字幕,目前支持srt和ass格式,

功能摘要:

 支持微调字幕,设置大小,颜色,位置

 

1 .字幕解析类

package com.hhzt.iptv.lvb_x.utils;

import android.os.Handler;
import android.util.Log;

import com.hhzt.iptv.lvb_x.Constant;
import com.hhzt.iptv.lvb_x.log.LogUtil;
import com.hhzt.iptv.lvb_x.model.Srt;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

public class SrtUtils {
   /**上一次 字幕节点*/
   private  static int node = 0;
   /**存放字幕*/
   private  static  List<Srt> srtlist = new ArrayList<Srt>();
   /**
    * 正则表达式,判断是否是时间的格式
    */
   private final static String equalStringExpress = "\\d\\d:\\d\\d:\\d\\d,\\d\\d\\d --> \\d\\d:\\d\\d:\\d\\d,\\d\\d\\d";
   /**
    * 正则表达式,判断是否是时间的格式
    */
   private final static String equalExpressAss = "\\d:\\d\\d:\\d\\d.\\d\\d";

   /**
    * 单位转换
    * 1秒=1000毫秒
    */
   private final static int oneSecond = 1000;

   private final static int oneMinute = 60 * oneSecond;

   private final static int oneHour = 60 * oneMinute;

   public static String getFileEncode(InputStream in) {
      String encode;
      byte[] b = new byte[3];
      try {
         in.read(b);
      } catch (IOException e) {
         e.printStackTrace();
      }
      if (b[0] == -17 && b[1] == -69 && b[2] == -65){
         encode="UTF-8";
      } else {
         encode="GBK";
      }
      return  encode;
   }
   /**
    *
    * @param time 毫秒
    * @return Srt
    */
   public static Srt getSrt(double time) {
//    System.out.println("上次节点"+node);
      Log.i("TAG","getSrtgetSrt:;"+time);
      int n=0;
      //根据上一次节点  开始查找
      for (int i = node; i < srtlist.size(); i++) {
         n++;
         Srt str=srtlist.get(i);
         //当时间小于 当前字幕段 开始时间时往回倒序查找
         if(time<str.getStar()){//小于开始时间
            for (int f = node -1 ; f >= 0; f--) { //  倒序查找
               n++;
               Srt stre=srtlist.get(f);
               if(stre.getStar()<=time && time<=stre.getEnd()){
                  node=f;//设置节点
                  //符合时间段返回
                  // System.out.println("总查询次数 : "+n);
                  return stre;
               }
            }
         }else{
            //当时间大于或等于 当前字幕段 开始时间时 顺序往下查找
            if(str.getStar()<=time && time<=str.getEnd()){
               node=i;//设置节点
               //符合时间段返回
//             System.out.println("总循环次数 : "+n);
               return str;
            }
         }
      }
      return null;
   }
   /***
    * 初始化字幕库
    *
    * @param path 本地文件路径
    * @return boolean
    */
   public static boolean srtInit(String path) {
      boolean b=false;
      File file = new File(path);
      InputStream inputStream=null;
      try {
         inputStream = new FileInputStream(file);
         String prefix=path.substring(path.lastIndexOf(".")+1);
         List<Srt> list =null;
         if("srt".equalsIgnoreCase(prefix)){
            list = parseSrt(inputStream);
         }else if("ass".equalsIgnoreCase(prefix)){
            list = parseAss(inputStream);
         }else{
            return b;
         }
         srtlist=list;
         node=0;
         if(srtlist!=null && srtlist.size()>0){
            b=true;
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      }finally{
         try {
            if(inputStream!=null ){
               inputStream.close();
            }
         } catch (IOException e1) {
            e1.printStackTrace();
         }
      }
      return b;
   }
   /***
    * 初始化字幕库
    * @param srturl 网络文件地址
    * @return boolean
    */
   public static boolean srtInitHttp(String srturl,  Handler handler) {
      boolean b=false;
      URL url = null;
      HttpURLConnection connection = null;
      InputStream in = null;
      try {
         url = new URL(URLEncoder(srturl));
         connection = (HttpURLConnection) url.openConnection();
         connection.setConnectTimeout(5000);
         connection.setReadTimeout(30000);
         in = connection.getInputStream();
         List<Srt> list =null;
         String prefix=srturl.substring(srturl.lastIndexOf(".")+1);
         if("srt".equalsIgnoreCase(prefix)){
            list = parseSrt(in);
         }else if("ass".equalsIgnoreCase(prefix)){
            list = parseAss(in);
         }else{
            return b;
         }
         srtlist=list;
         node=0;
         if(srtlist!=null && srtlist.size()>0){
            handler.sendEmptyMessage(Constant.IPTV_MSG_ANALYSIS_SUCCESS);
            b=true;
         }
      } catch (Exception e) {
         LogUtil.e("TAG","EEEEEEEE:"+e.getMessage());
         e.printStackTrace();
      } finally {
         if (connection != null) {
            connection.disconnect();
         }
         if (in != null) {
            try {
               in.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
      return b;
   }
   /***
    * 清除字幕库
    * @return
    */
   public static boolean srtClear() {
      try {
         if(srtlist!=null && srtlist.size()>0){
            srtlist.clear();
            return true;
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
      return false;
   }
   /***
    * 修改字幕 当前加载的
    * @param timeError     需要调整的时间秒数,正数为延迟,负数为提早
    */
   public static boolean update(double timeError) {
      int time=(int)(timeError*1000);
      for (Srt srt : srtlist) {
         srt.setStar(srt.getStar()+time);
         srt.setEnd(srt.getEnd()+time);
      }
      return false;

   }
   /***
    * 修改字幕
    * @param file 源字幕文件位置
    * @param timeError     需要调整的时间秒数,正数为延迟,负数为提早
    * @param file  新的字幕文件保存位置
    */
   public static boolean update(File file,double timeError) {
      boolean b=false;
      long time=(long)(timeError*1000);
      String path=file.getPath();
      String prefix=path.substring(path.lastIndexOf(".")+1);
      if("srt".equalsIgnoreCase(prefix)){
         b= updateSrt(file,time);
      }else if("ass".equalsIgnoreCase(prefix)){
         b=updateAss(file, time);
      }
      return b;
   }
   private static boolean updateSrt(File file,long timeError){
      boolean b=false;
      InputStream inputStream=null;
      OutputStream outputStream=null;
      BufferedReader in=null;
      BufferedWriter outWriter=null;

      File newfile=new File(file.getParentFile().getAbsolutePath()+"/new_"+file.getName());
      String line=null;
      StringBuffer newLine=new StringBuffer();

      try {
         newfile.createNewFile();     //创建新文件
         inputStream = new FileInputStream(file);
         outputStream=new FileOutputStream(newfile);

         in = new BufferedReader(new InputStreamReader(inputStream,getFileEncode(inputStream))); //创建文件输入流
         outWriter = new BufferedWriter(new OutputStreamWriter(outputStream,getFileEncode(inputStream)));//缓冲  //创建文件输出流

         //以下while循环逐行读取字幕源文件
         while((line=in.readLine()) != null) {
            if (! Pattern.matches(equalStringExpress,line)){     //进行正则式的匹配。
               outWriter.write(line+"\r\n");//println(newLine.toString());   //如果读到的不是时间描述字符行,则原样写入新文件
               outWriter.flush();
               continue;              //提早结束本次循环继续读取下一行
            }
            //以下对时间描述字符行进行格式转换和数学运算
            String times=line.substring(0,12);
            Date date= stringToDate(times, "HH:mm:ss,SSS");
            Date date2= getTimeValueSSS(date,timeError);
            times=dateToString(date2, "HH:mm:ss,SSS");
                /*
                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=timeError  + second + minute*60 + hour*3600;
                String shour= "0" + (times/3600);
                String sminute="0" + ((times % 3600)/60);
                String ssecond="0" + (times % 60);

                int second2=Integer.parseInt(line.substring(23,25));
                int minute2=Integer.parseInt(line.substring(20,22));
                int hour2=Integer.parseInt(line.substring(17,19));
                times=timeError     + second2 + minute2*60 + hour2*3600;

                String shour2= "0" + (times/3600);
                String sminute2="0" + ((times % 3600)/60);
                String ssecond2="0" + (times % 60);
                */
            String times2=line.substring(17,29);
            date= stringToDate(times2, "HH:mm:ss,SSS");
            date2= getTimeValueSSS(date,timeError);
            times2=dateToString(date2, "HH:mm:ss,SSS");

            newLine.setLength(0);
            newLine.append(times + " --> ");
            newLine.append(times2);
            //最后把得到的时间描述字符行写入新文件
            outWriter.write(newLine+"\r\n");//println(newLine.toString());
            outWriter.flush();
         }
         in.close();
         outWriter.close();
         String filename=file.getName();
         deleteFile(file.getPath());
         renameFile(newfile.getParentFile().getAbsolutePath(), newfile.getName(),filename);
         b=true;
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
      }catch (IOException ex) {
         ex.printStackTrace();
      }finally{
         if(inputStream!=null){
            try {
               inputStream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(outputStream!=null){
            try {
               outputStream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(outWriter!=null){
            try {
               outWriter.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(in!=null){
            try {
               in.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
      return b;
   }
   private static boolean updateAss(File file,long timeError){
      boolean b=false;
      InputStream inputStream=null;
      OutputStream outputStream=null;
      BufferedReader in=null;
      BufferedWriter outWriter=null;

      File newfile=new File(file.getParentFile().getAbsolutePath()+"/new_"+file.getName());
      String line=null;
      StringBuffer newLine=new StringBuffer();

      try {
         newfile.createNewFile();     //创建新文件
         inputStream = new FileInputStream(file);
         outputStream=new FileOutputStream(newfile);

         in = new BufferedReader(new InputStreamReader(inputStream,getFileEncode(inputStream))); //创建文件输入流
         outWriter = new BufferedWriter(new OutputStreamWriter(outputStream,getFileEncode(inputStream)));//缓冲  //创建文件输出流

         int startIndex=-1;//事件开始的时间
         int endIndex=-1;// 事件结束的时间
         int textIndex=-1;//为对白字幕区域
         int marginLIndex=-1;//与左边缘的距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         int marginRIndex=-1;//与右边缘的距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         int marginVIndex=-1;//垂直距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         boolean events=false;
         //以下while循环逐行读取字幕源文件
         while((line=in.readLine()) != null) {
            if ("[Events]".equals(line)){
               events=true;
            }
            if(line!=null && line.length()>0 && line.indexOf(",")>-1){
               if(startIndex>-1 && endIndex>-1){
                  // 填充开始时间数据
                  String[] contexts= line.split(",", 10);
                  String startime =contexts[startIndex];
                  // 填充开始时间数据
                  if(Pattern.matches("\\d:\\d\\d:\\d\\d.\\d\\d", startime)){
                     Date date= stringToDate(startime+"0", "H:mm:ss.SSS");
                     Date date2= getTimeValueSSS(date,timeError);
                     String strtime=dateToString(date2, "H:mm:ss.SSS");
                     contexts[startIndex]=strtime.substring(0, strtime.length()-1);
                  }
                  // 填充结束时间数据
                  String endtime =contexts[endIndex];;
                  if(Pattern.matches("\\d:\\d\\d:\\d\\d.\\d\\d", endtime)){
                     Date date= stringToDate(endtime+"0", "H:mm:ss.SSS");
                     Date date2= getTimeValueSSS(date,timeError);
                     String strtime=dateToString(date2, "H:mm:ss.SSS");
                     contexts[endIndex]=strtime.substring(0, strtime.length()-1);
                  }
                  newLine.setLength(0);
                  for (int i = 0; i < contexts.length; i++) {
                     if(i>0){
                        newLine.append(",");
                     }
                     newLine.append(contexts[i]);
                  }
                  //最后把得到的时间描述字符行写入新文件
                  outWriter.write(newLine.toString()+"\r\n");//println(newLine.toString());
                  outWriter.flush();
                  continue;
               }else{
                  if(events){
                     if(line.startsWith("Format")){
                        String[] formats= line.split(",");
                        for (int i = 0; i < formats.length; i++) {
                           if("Start".equals(formats[i].trim())){
                              startIndex=i;
                           }else
                           if("End".equals(formats[i].trim())){
                              endIndex=i;
                           }else
                           if("Text".equals(formats[i].trim())){
                              textIndex=i;
                           }else
                           if("MarginL".equals(formats[i].trim())){
                              marginLIndex=i;
                           }else
                           if("MarginR".equals(formats[i].trim())){
                              marginRIndex=i;
                           }else
                           if("MarginV".equals(formats[i].trim())){
                              marginVIndex=i;
                           }
                        }
                     }
                  }
               }
            }
            //不修改直接写入
            outWriter.write(line+"\r\n");
            outWriter.flush();
         }
         in.close();
         outWriter.close();
         String filename=file.getName();
         deleteFile(file.getPath());
         renameFile(newfile.getParentFile().getAbsolutePath(), newfile.getName(),filename);
         b=true;
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
      }catch (IOException ex) {
         ex.printStackTrace();
      }catch (Exception ex) {
//         System.out.println(newLine);
         ex.printStackTrace();
      }finally{
         if(inputStream!=null){
            try {
               inputStream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(outputStream!=null){
            try {
               outputStream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(outWriter!=null){
            try {
               outWriter.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         if(in!=null){
            try {
               in.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
      return b;
   }
   public static boolean renameFile(String path,String oldname,String newname){
      File oldfile=new File(path+"/"+oldname);
      File newfile=new File(path+"/"+newname);
      if(!oldfile.exists()){
         return false;//重命名文件不存在
      }
      if(!oldname.equals(newname)){//新的文件名和以前文件名不同时,才有必要进行重命名
         if(newfile.exists())//若在该目录下已经有一个文件和新文件名相同,则不允许重命名
            return false ;
         else{
            oldfile.renameTo(newfile);
            return true;
         }
      }else{
         return true;
      }
   }
   public static boolean deleteFile(String fileName) {
      File file = new File(fileName);
      // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
      if (file.exists() && file.isFile()) {
         if (file.delete()) {
            //      System.out.println("删除单个文件" + fileName + "成功!");
            return true;
         } else {
            //      System.out.println("删除单个文件" + fileName + "失败!");
            return false;
         }
      } else {
         //  System.out.println("删除单个文件失败:" + fileName + "不存在!");
         return false;
      }
   }
   /**
    * 解析字幕
    *
    * @param inputStream
    *            字幕路径
    */
   private static List<Srt> parseSrt(InputStream inputStream) {
      ArrayList<Srt> list = new ArrayList<Srt>();
      BufferedReader bufferedReader = null;
      try {
         bufferedReader = new BufferedReader(new InputStreamReader(inputStream,getFileEncode(inputStream)));
      } catch (UnsupportedEncodingException e1) {
         e1.printStackTrace();
      }
      String line = null;
      try {

         while ((line = bufferedReader.readLine()) != null) {
            Srt sm = new Srt();
            // 匹配正则表达式,不符合提前结束当前行;
            if (Pattern.matches(equalStringExpress, line)){
               // 填充开始时间数据
               sm.star = getTime(line.substring(0, 12));
               // 填充结束时间数据
               sm.end = getTime(line.substring(17, 29));
               // 填充中文数据
               sm.contextC = bufferedReader.readLine();
               // 填充英文数据
               sm.contextE = bufferedReader.readLine();
               // 当前字幕的节点位置
               sm.node = list.size() + 1;
               list.add(sm);
            }
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
      return list;
   }
   /**
    * 解析字幕
    *
    * @param inputStream
    *            字幕路径
    */
   private static List<Srt> parseAss(InputStream inputStream) {
      ArrayList<Srt> list = new ArrayList<Srt>();
      BufferedReader bufferedReader = null;
      try {
         bufferedReader = new BufferedReader(new InputStreamReader(inputStream,getFileEncode(inputStream)));
      } catch (UnsupportedEncodingException e1) {
         e1.printStackTrace();
      }
      String line = null;
      try {
         int startIndex=-1;//事件开始的时间
         int endIndex=-1;// 事件结束的时间
         int textIndex=-1;//为对白字幕区域
         int marginLIndex=-1;//与左边缘的距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         int marginRIndex=-1;//与右边缘的距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         int marginVIndex=-1;//垂直距离, 为4位数字代表的像素值. 0000代表使用当前Style定义的值
         boolean events=false;

         while ((line = bufferedReader.readLine()) != null) {
            if ("[Events]".equals(line)){
               events=true;
            }
            if(events){
               if(line!=null && line.length()>0 && line.indexOf(",")>-1){
                  if(line.startsWith("Format")){
                     String[] formats= line.split(",");
                     for (int i = 0; i < formats.length; i++) {
                        if("Start".equals(formats[i].trim())){
                           startIndex=i;
                        }else
                        if("End".equals(formats[i].trim())){
                           endIndex=i;
                        }else
                        if("Text".equals(formats[i].trim())){
                           textIndex=i;
                        }else
                        if("MarginL".equals(formats[i].trim())){
                           marginLIndex=i;
                        }else
                        if("MarginR".equals(formats[i].trim())){
                           marginRIndex=i;
                        }else
                        if("MarginV".equals(formats[i].trim())){
                           marginVIndex=i;
                        }
                     }
                  }else{
                     Srt sm = new Srt();
                     String[] contexts= line.split(",", 10);
                     if(startIndex>-1){
                        // 填充开始时间数据
                        String startime =contexts[startIndex].replace(".",",")+"0";
                        if(Pattern.matches("\\d:\\d\\d:\\d\\d,\\d\\d\\d", startime)){
                           startime="0"+startime;
                        }
                        sm.star = getTime(startime);
                     }
                     if(endIndex>-1){
                        // 填充结束时间数据
                        String endtime =contexts[endIndex].replace(".",",")+"0";
                        if(Pattern.matches("\\d:\\d\\d:\\d\\d,\\d\\d\\d", endtime)){
                           endtime="0"+endtime;
                        }
                        sm.end = getTime(endtime);
                     }
                     if(textIndex>-1){
                        String text=contexts[textIndex];
                        if(text.indexOf("\\n")>-1){

                           String[] strs=text.replace("\\n", "@_@").split("@_@",2);
                           sm.contextC =strs[0];
                           // 填充英文数据
                           sm.contextE =strs[1];
                        }else if (text.indexOf("\\N")>-1){

                           String[] strs=text.replace("\\N", "@_@").split("@_@",2);
                           sm.contextC =strs[0];
                           // 填充英文数据
                           sm.contextE =strs[1];
                        }else{
                           // 填充中文数据
                           sm.contextC =text;
                        }
                     }
                     // 当前字幕的节点位置
                     sm.node = list.size() + 1;
                     list.add(sm);
                  }
               }
            }
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
      return list;
   }
   /**
    * @param line
    * @return 字幕所在的时间节点
    * @descraption 将String类型的时间转换成int的时间类型
    */
   private static int getTime(String line){
      try
      {
//         0:00:05.00+0
//         00:00:21,715
//         System.out.println(line);
         return Integer.parseInt(line.substring(0, 2)) * oneHour// 时
               + Integer.parseInt(line.substring(3, 5)) * oneMinute// 分
               + Integer.parseInt(line.substring(6, 8)) * oneSecond// 秒
               + Integer.parseInt(line.substring(9, line.length()));// 毫秒
      }
      catch (NumberFormatException e)
      {
         e.printStackTrace();
      }
      return -1;
   }
   //指定日期毫秒后的日期
   private static Date getTimeValueSSS(Date d,long l){
      Calendar cal=Calendar.getInstance();
      cal.setTime(d);
      cal.setTimeInMillis(cal.getTimeInMillis()+l);
      return cal.getTime();
   }
   /**
    * 字符串转换日期
    * @param str
    * @param formatprn 格式
    * @return
    */
   private static Date stringToDate(String str,String formatprn){
      //str =  " 2008-07-10 19:20:00 " 格式
      SimpleDateFormat format = new SimpleDateFormat(formatprn);
      if(!str.equals("")&&str!=null){
         try {
            return format.parse(str);
         } catch (ParseException e) {
            e.printStackTrace();
         }
      }
      return null;
   }
   /**
    * 日期转换成字符串
    * @param date
    * @param formatprn 格式
    * @return
    */
   private static String dateToString(Date date,String formatprn){
      SimpleDateFormat format = new SimpleDateFormat(formatprn);
      return format.format(date);
   }

   // 完整的判断中文汉字和符号
   public static String URLEncoder(String urls) {
      String[] urls2=urls.split("/");
      StringBuffer srt=new StringBuffer();
      for (int i = 0; i < urls2.length; i++) {
         if(urls2[i]!=null && urls2[i].length()>0){

            try {
               if(isChinese(urls2[i])){
                  srt.append(URLEncoder.encode(urls2[i], "utf-8"));
               }else{
                  srt.append(urls2[i]);
               }
               if("http:".equals(urls2[i])|| "https:".equals(urls2[i])){
                  srt.append("//");
               }else if(i < urls2.length-1){
                  srt.append("/");
               }
            } catch (UnsupportedEncodingException e) {
               e.printStackTrace();
            }
         }
      }
      return srt.toString();
   }
   // 完整的判断中文汉字和符号
   public static boolean isChinese(String strName) {
      char[] ch = strName.toCharArray();
      for (int i = 0; i < ch.length; i++) {
         char c = ch[i];
         if (isChinese(c)) {
            return true;
         }
      }
      return false;
   }

   // 根据Unicode编码完美的判断中文汉字和符号
   private static boolean isChinese(char c) {
      Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
      if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
            || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
            || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
            || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
         return true;
      }
      return false;
   }
}
2.字幕实体类
package com.hhzt.iptv.lvb_x.model;
/**
 *
 * @author Administrator
 * 字幕的实体类
 */
public class Srt {
   /**
    * 当前节点
    */
   public int node;

   /**
    * 开始显示的时间
    */
   public int star;

   /**
    * 结束显示的时间
    */
   public int end;

   /**
    * 显示的内容《英文》
    */
   public String contextE;

   /**
    * 显示的内容《中文》
    */
   public String contextC;

   public int getNode() {
      return node;
   }

   public void setNode(int node) {
      this.node = node;
   }

   public int getStar() {
      return star;
   }

   public void setStar(int star) {
      this.star = star;
   }

   public int getEnd() {
      return end;
   }

   public void setEnd(int end) {
      this.end = end;
   }
   /**原生英文字幕*/
   public String getContextE() {
      return contextE;
   }
   /**英文字幕去除 前缀*/
   public String getContextEn() {
      if(contextE!=null && contextE.length()>0){
         String regex="\\{.+?\\}";
         return contextE.replaceAll(regex,"").replace("{\\fs12}", "");
      }
      return contextE;
   }
   public void setContextE(String contextE) {
      this.contextE = contextE;
   }
   /**中文文字幕去除  样式格式*/
   public String getContextCn() {
      if(contextC!=null && contextC.length()>0){
         String regex="\\{.+?\\}";
         return contextC.replaceAll(regex, "");
      }
      return contextC;
   }
   public String getContextC() {
      return contextC;
   }

   public void setContextC(String contextC) {
      this.contextC = contextC;
   }

   @Override
   public String toString() {
      return "Srt{" +
            "node=" + node +
            ", star=" + star +
            ", end=" + end +
            ", contextE='" + contextE + '\'' +
            ", contextC='" + contextC + '\'' +
            '}';
   }
}

3.activity调用
public static class NetUtil2 extends Thread {
    private boolean isClose = false;
    private boolean isPause = false;
    /**
     * 暂停线程
     */
    public synchronized void onThreadPause() {
        isPause = true;
    }

    /**
     * 线程等待,不提供给外部调用
     */
    private void onThreadWait() {
        try {
            synchronized (this) {
                this.wait();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 线程继续运行
     */
    public synchronized void onThreadResume() {
        isPause = false;
        this.notify();
    }

    /**
     * 关闭线程
     */
    public synchronized void closeThread() {
        try {
            notify();
            setClose(true);
            interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isClose() {
        return isClose;
    }

    public void setClose(boolean isClose) {
        this.isClose = isClose;
    }

    @Override
    public void run() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
        while (!isClose && !isInterrupted()) {
            if (!isPause) {
                if(!isGetReady && null ==mMediaPlayer){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }

                final Srt str = SrtUtils.getSrt(mMediaPlayer.getCurrentPosition()+value);
                 LogUtil.i("TAG","SrtSrt::"+mMediaPlayer.getCurrentPosition());
                if(null == str){
                    try {
                        Thread.sleep(10);
                        continue;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    LogUtil.i("TAG","getContextC11::"+str.getContextC());
                    LogUtil.i("TAG","tinme::"+str.getStar());
                    LogUtil.i("TAG","tinmeend::"+str.getEnd());

                    if(!str.getContextC().equalsIgnoreCase(text)){
                        LogUtil.i("TAG","getContextC11::"+str.getContextC());
                        LogUtil.i("TAG","getContextC22::"+str.getStar());
                        text = str.getContextCn();
                        text_en = str.getContextEn();
                        isTime = str.getEnd()-(int)value;
                        mMediaPlayerHandler.removeMessages(Constant.IPTV_MSG_SHOW_ANALYSIS);
                        mMediaPlayerHandler.sendEmptyMessage(Constant.IPTV_MSG_SHOW_ANALYSIS);
                    }}
            } else {
                onThreadWait();
            }
        }
    }
}

Android 为TV端助力