Android 您所在的位置:网站首页 字幕文件软件下载安装 Android

Android

2024-05-31 09:52| 来源: 网络整理| 查看: 265

SRT字幕文件的下载、解压、显示 简介下载创建文件夹文件下载下载调用以及文件解析调用 解析ZIP文件解析外部引用 转换转换SRT字幕文件获取SRT文件list实体数据 显示字幕显示

简介

需要在视频播放时,同步显示字幕,市面上主流的字幕文件一般为SRT文件,一般流程为:从服务器请求一个url地址,此为zip字幕压缩文件,一般需要请求url,下载zip文件,解析zip文件得到字幕srt文件,最后进行显示

下载

请求就不在此多言了,每个服务器请求体,返回题各异,没有参考价值。 下载zip文件我们需要在本地创建一个本地文件夹用来存储此文件。

创建文件夹 public String createDirectory(String name) { File dir = new File(BaseApplication.getContext().getCacheDir(), name); File file = BaseApplication.getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); if (file != null) { dir = new File(file, name); } if (!dir.exists()) { dir.mkdirs(); } return dir.toString(); } 文件下载

文件下载使用的开源框架Filedownloader

implementation 'com.liulishuo.filedownloader:library:1.7.7'//download

参数一:下载地址 参数二:文件存储地址 参数三:回调 从外部传入需要的下载参数,然后通过callback回调出去,进行页面更新操作

public void StartDownloadFile(String url,String path,FileDownloaderCallback callback){ FileDownloader.getImpl().create(url).setPath(path,true).setListener(new FileDownloadListener() { @Override protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) { callback.start(); } @Override protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) { } @Override protected void completed(BaseDownloadTask task) { callback.completed(task.getPath()); } @Override protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) { } @Override protected void error(BaseDownloadTask task, Throwable e) { callback.failed(); } @Override protected void warn(BaseDownloadTask task) { } }).start(); } 下载调用以及文件解析调用

此处建立文件下载文件夹以及解析完成的文件夹地址,然后通过调用上述filedownloader文件下载回调,然后在下载完成的回调中进行文件zip解析

public void download(String url,String title,DownloadResultCallback callback){ String input = "InputDirectory"; String output = "OutputDirectory"; String inPath = FileUtils.getInstance().createDirectory(input); String outPath = FileUtils.getInstance().createDirectory(output); String sub = FileUtils.getInstance().createFile(inPath,"subTitleFile"+ File.separator); DownloadUtils.getInstance().StartDownloadFile(url, sub, new DownloadUtils.FileDownloaderCallback() { @Override public void start() { callback.downloadStart(); } @Override public void completed(String inputPath) { callback.downloadSuccess(); String path = inputPath + "/" + title +".zip"; try { ZipUtils.UnZipFolder(path,outPath); callback.resolveSuccess(); } catch (Exception e) { callback.resolveFailed(e.getMessage()); e.printStackTrace(); } } @Override public void failed() { callback.downloadFailed(); } }); } 解析 ZIP文件解析

此处被上述调用,用于zip文件解析 参数一:需要被解析的zip文件地址 参数二:输出文件夹地址

public class ZipUtils { public static void UnZipFolder(String zipFileString, String outPathString)throws Exception { java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(zipFileString)); java.util.zip.ZipEntry zipEntry; String szName = ""; while ((zipEntry = inZip.getNextEntry()) != null) { szName = zipEntry.getName(); if (zipEntry.isDirectory()) { // get the folder name of the widget szName = szName.substring(0, szName.length() - 1); java.io.File folder = new java.io.File(outPathString + java.io.File.separator + szName); folder.mkdirs(); } else { java.io.File file = new java.io.File(outPathString + java.io.File.separator + szName); file.createNewFile(); // get the output stream of the file java.io.FileOutputStream out = new java.io.FileOutputStream(file); int len; byte[] buffer = new byte[1024]; // read (len) bytes into buffer while ((len = inZip.read(buffer)) != -1) { // write (len) byte from buffer at the position 0 out.write(buffer, 0, len); out.flush(); } out.close(); } }//end of while inZip.close(); }//end o } 外部引用

参数一:下载url地址 参数二:存储文件夹名称 参数三:callback 上述zip文件下载以及zip文件解析为一个封装类,此处为在外部传入参数,通过回调进行页面更新,然后在resolveSuccess()方法中进行异步操作(此方法代表zip文件被下载成功并且已被成功解析)

private void download(){ if (titleBeanList == null || titleBeanList.size() == 0)return; if (curSubTitlePos == 0)return; DownloadUtils.getInstance().download(titleBeanList.get(curSubTitlePos).getSub(), titleBeanList.get(curSubTitlePos).getT_name(), new DownloadUtils.DownloadResultCallback() { @Override public void downloadStart() { Log.d(TAG,"download start"); } @Override public void downloadSuccess() { Log.d(TAG,"download success"); } @Override public void downloadFailed() { Log.d(TAG,"download fail"); } @Override public void resolveSuccess() { Log.d(TAG,"resolve success"); handler.sendEmptyMessage(6); } @Override public void resolveFailed(String failMsg) { Log.d(TAG,"resolve error:"+failMsg); } }); } 转换 转换SRT字幕文件

通过将本地的SRT字幕文件转为相对应集合实体数据,具体实体类型根据SRT文件内容而定

public static List getSrtInfoList(String srtPath){ List srtList = new ArrayList(); try { InputStreamReader read = new InputStreamReader(new FileInputStream(srtPath), "utf-8"); BufferedReader bufferedReader = new BufferedReader(read); String textLine; CursorStatus cursorStatus = CursorStatus.NONE; SrtEntity entity = null; while ((textLine = bufferedReader.readLine()) != null){ textLine = textLine.trim(); if (cursorStatus == CursorStatus.NONE) { if (textLine.isEmpty()) { continue; } if (!isNumeric(textLine)){ continue; } // New cue entity = new SrtEntity(); // First textLine is the cue number try { entity.setNumber(Integer.parseInt(textLine)); } catch (NumberFormatException e) { } cursorStatus = CursorStatus.CUE_ID; continue; } // Second textLine defines the start and end time codes // 00:01:21,456 --> 00:01:23,417 if (cursorStatus == CursorStatus.CUE_ID) { if (!textLine.substring(13, 16).equals("-->")) { throw new Exception(String.format( "Timecode textLine is badly formated: %s", textLine)); } entity.setBg(parseTimeCode(textLine.substring(0, 12))); entity.setEd(parseTimeCode(textLine.substring(17))); cursorStatus = CursorStatus.CUE_TIMECODE; continue; } // Following lines are the cue lines if (!textLine.isEmpty() && ( cursorStatus == CursorStatus.CUE_TIMECODE || cursorStatus == CursorStatus.CUE_TEXT)) { entity.addLine(textLine); cursorStatus = CursorStatus.CUE_TEXT; continue; } if (cursorStatus == CursorStatus.CUE_TIMECODE && textLine.isEmpty()) { entity.addLine(textLine); cursorStatus = CursorStatus.CUE_TEXT; continue; } if (cursorStatus == CursorStatus.CUE_TEXT && textLine.isEmpty()) { // End of cue srtList.add(entity); entity = null; cursorStatus = CursorStatus.NONE; continue; } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } catch (FileNotFoundException e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } return srtList; } 获取SRT文件list实体数据

通过以上步骤之后,即可将SRT文件转为相对应的list实体数据,最后与视频声音进行同步即可达到字幕与声音同步的效果

String outPath = FileUtils.getInstance().createDirectory("OutputDirectory"); String path = outPath +"/" +titleBeanList.get(curSubTitlePos).getT_name(); srtEntityList.addAll(SrtParser.getSrtInfoList(path)); 显示 字幕显示

然后通过获取字幕文件的片段的开始时间与结束时间,若当前视频的播放进度在此范围之内,即显示字幕,否则继续寻找;

private void showSubTitle(){ if (srtEntityList == null || srtEntityList.size() == 0)return; for (int i = curSubTitleNum; i < srtEntityList.size(); i++) { long start = srtEntityList.get(i).getBg().getTime()+subtitleSpeed; long end = srtEntityList.get(i).getEd().getTime()+subtitleSpeed; if (curProgress >= start && curProgress


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有