iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >AndroidSRT字幕文件基础操作讲解
  • 203
分享到

AndroidSRT字幕文件基础操作讲解

AndroidSRT字幕文件AndroidSRTAndroid字幕文件 2023-01-16 18:01:28 203人浏览 安东尼
摘要

目录简介下载创建文件夹文件下载下载调用以及文件解析调用解析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<SrtEntity> getSrtInfoList(String srtPath){
        List<SrtEntity> 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 <= end){
                
                binding.VideoPlay.setSubTitle(srtEntityList.get(i).content.getText());
                curSubTitleNum = i;
                break;
            }
        }
    }

若用户往前拖动视频进度条,则将字幕文件片段下标置为0,从头开始匹配

 if (currentPosition - curProgress < 0){
                            //seek --
                            curSubTitleNum = 0;
                        }

到此这篇关于Android SRT字幕文件基础操作讲解的文章就介绍到这了,更多相关Android SRT字幕文件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: AndroidSRT字幕文件基础操作讲解

本文链接: https://www.lsjlt.com/news/177915.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • AndroidSRT字幕文件基础操作讲解
    目录简介下载创建文件夹文件下载下载调用以及文件解析调用解析ZIP文件解析外部引用转换转换SRT字幕文件获取SRT文件list实体数据显示字幕显示简介 需要在视频播放时,同步显示字幕,...
    99+
    2023-01-16
    Android SRT字幕文件 Android SRT Android字幕文件
  • python文件操作的基础详细讲解(write、read、readlines、readline)
    目录前言1 文件操作1.1 文件打开与关闭1.1.1 打开文件1.1.2 关闭文件2 文件读写2.1 写数据(write)2.2 读数据(read)2.3 读数据(readlines...
    99+
    2022-11-10
  • python3基础:文件操作
    相对路径和绝对路径 相对路径:顾名思义就是相对于当前文件的路径。网页中一般表示路径使用这个方法。 绝对路径:绝对路径就是主页上的文件或目录在硬盘上真正的路径。 比如 c:/apache/cgi-bin 下的,那么 c:/apach...
    99+
    2023-01-31
    操作 文件 基础
  • C++中文件操作基础详解
    目录文件操作文件分类文本文件写文件读文件二进制文件写文件读文件文件操作 意义:利用文件操作可以保存我们程序运行的信息,是持久化技术的体现 文件分类 按文件类型分为: 1、文本文件 &...
    99+
    2022-11-13
  • python文件基础之(文件操作)
        在之前学习了python的列表、元组、集合等知识,接下来将python的文件相关的知识做一总结和分析。一 open函数 在我们用word、excel、vim对文件操作时,肯定要先打开文件,同样在编程里面也是需要将文件打开,然后再对文...
    99+
    2023-01-31
    文件 操作 基础
  • Linux基础IO【文件理解与操作】
    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Great minds discuss ide...
    99+
    2023-08-18
    linux 服务器 运维 云原生 基础IO
  • python基础之文件操作
    目录1、打开文件2、写入3、追加4、读文件5、文件拷贝6、tell()7、truncate(size)8、seek()1、打开文件 open()函数简介 : 打开文件使用open函数...
    99+
    2022-11-12
  • Python基础:文件的操作
    一、python可以在不导入任何模块的情况下对文件完成读、写、追加,替换(稍复杂)。二、打开文件:        1、f = open('text.txt')            这种方式打开,操作完后需要使用f.colse()关闭。  ...
    99+
    2023-01-31
    操作 文件 基础
  • python基础-文件操作(10)
    一、什么是文件 等等这些都叫做文件,各种格式的。但不仅仅限制于这些。   二、文件的作用 大家应该听说过一句话:“好记性不如烂笔头”。 不仅人的大脑会遗忘事情,计算机也会如此,比如一个程序在运行过程中用了九牛二虎之力终于计算出了结果,试...
    99+
    2023-01-31
    操作 文件 基础
  • python字符串基础操作详解
    目录字符串的赋值单引号字符串赋值给变量双引号字符串赋值给变量三引号字符串赋值给变量(多行)字符串的截取截取指定位置的字符获取指定位置之后的所有字符截取指定位置之前的所有字符获取所有的...
    99+
    2022-11-13
  • Java对文件进行基本操作案例讲解
    File文件类 java.io.File是文件和目录的重要类(JDK6及以前是唯一) 目录也使用File类进行表示 File类与操作系统无关,但会受到操作系...
    99+
    2022-11-12
  • Java基础之文件和目录操作
    目录一、前言二、构造方法三、文件元数据四、文件操作五、目录操作六、总结一、前言 文件和目录操作最终是与操作系统和文件系统相关的,不同系统的 实现是不一样的,但Java中的java.i...
    99+
    2022-11-12
  • Java Io File文件操作基础教程
    目录File 类概述File对象文件操作File静态方法获取各种路径路径整合获取classpath路径 (常用)获取Tomcat的bin目录常用功能创建目录创建文件判断文件或文件夹是...
    99+
    2022-11-13
  • Python基础之文件操作及光标移动详解
    目录一、文件操作1、文件的概念2、代码打开文件的方式二、文件读写模式1、'r' 只读模式 read2、'w' 只写模式 write3、'a&#...
    99+
    2022-11-11
  • python shutil操作文件实例讲解
    1、使用函数shutil.make_archive()创建归档文件,并返回归档后的名称。 import shutil path_1 = r'D:\PycharmProjects\...
    99+
    2022-11-11
  • MySQL增删改查【基础篇】5000字图文超详细讲解
    MySQL增删改查[基础篇]【5000字图文超详细讲解】 MySQL的CRUD一.CURD1.CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete) 二.新增(Create)1....
    99+
    2023-08-18
    mysql 数据库 sql
  • Git基础学习之文件删除操作命令详解
    目录1、删除文件说明2、删除文件操作(1)仅删除暂存区的文件(2)完全删除文件3、本文用到的命令总结1、删除文件说明 在Git工作目录中要删除某个文件,首先要清楚该文件所处的状态。 ...
    99+
    2022-11-13
    Git文件删除操作 Git文件删除
  • Node.js基础入门之缓存区与文件操作详解
    目录缓存区1. 什么是缓存区?2. 创建指定长度的缓存区3. 通过数组创建缓存区4. 通过字符串创建缓存区5. 读写缓存区6. 复制缓存区文件操作1. 异步直接读取2. 同步直接读取...
    99+
    2022-11-13
  • python基础之文件操作和异常处理
    目录一、文件和异常1.1从文件中读取数据1.2open()1.3关键字with1.4read()二、逐行读取三、创建一个包含文件各行内容的列表3.1readlines()四、查找字符...
    99+
    2022-11-12
  • Scala文件操作示例代码讲解
    目录1. 读取数据1.1 按行读取1.2 按字符读取Scala使用source.buffered方法按字符读取文件一个示例1.3 读取词法单元和数字1.4 从URL或者其他源读取数据...
    99+
    2023-05-14
    Scala文件操作 Scala写入文件
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作