zoukankan      html  css  js  c++  java
  • Android MediaPlayer 字幕同步【2】

    之前说了MediaPlayer如何实现字幕显示,但是API需要16以上。那如何系统不支持的话我们可以自己实现。

    大致思想如下:

    从网上获取srt文件后(可以保存在本地/或者不保存)解析srt文件,随后根据Player播放不断的刷新字幕来实现同步机制。

    srt解析

    网上随便下了一个电影的字幕srt文件,
    1
    00:00:00,000 --> 00:00:10,000
    (内容空白)
    .....(省略若干行)
    4
    00:00:43,780 --> 00:00:49,230
    We were once a peaceful race of intelligent mechanical beings.

    5
    00:00:50,070 --> 00:00:52,570
    But then came the war.

    格式
    id
    开始时间 --> 结束时间
    内容
    (回车空行)

    如何解析srt文件网上很蛮多的介绍,大家可以搜索下。
    我是这样解析的:
     BufferedReader bufferReader = new BufferedReader(new InputStreamReader(
                    inputStream, CHAR_SET));
    
            StringBuilder builder = new StringBuilder();
            String line = bufferReader.readLine();
    
            while (line != null)
            {
                if (isBlankString(line))
                {
                    builder.append("@");
                }
                else
                {
                    builder.append(line + "#");
                }
                line = bufferReader.readLine();
            }
            return builder.toString();
    循环读取文件,每次读一行,是回车空行@结尾,否则#结尾...然后把这个String以@分成数组(String中会出现@@这种情况注意下就可以了)
    基本数组的每一项 就是一个节点。然后可以通过#字符,解析id,startTime,endTime,data。
    最后可以在ArrayList<Srt>中....

    srt同步

    在Player中都会有控制条,应该没人会用系统的VideoView吧。这样的话就需要实现控制条当前时间的显示,seekBar同步等等。
    基本思想就是有一个线程不断的刷新当前状态更新UI,这样的话我们就能拿到实时的播放信息来控制字幕的同步了。

    根据当前的播放时间,找到srt文件,然后显示。
    这个方法不断的被调用..
    public synchronized void onUpdate(int percent, int currentPosition,
                int duration)
        {
            if (hasSubtitleData()
                    && mSrtHelper.onUpdate(percent, currentPosition, duration))
            {
                Srt srt = findRightSrt(percent, currentPosition, duration);
                if (srt == null && mLogger != null)
                {
                    mLogger.log("can not find the right srt.");
                }
    
                int id = srt.getId();
                int startTime = srt.getStartTime();
                int endTime = srt.getEndTime();
                if (id != mSrtHelper.id && currentPosition >= startTime
                        && currentPosition <= endTime)
                {
                    mSrtHelper.id = id;
    
                    setSubtitle(srt.getData());
                }
                else if (mSrtHelper.id == id
                        && (currentPosition < startTime || currentPosition > endTime))
                {
                    setSubtitle(BLANK);
                }
    
                if (mLogger != null)
                {
                    mLogger.log(srt);
                }
            }
        }


    private Srt findRightSrt(int percent, int currentPosition, int duration)
        {
            if (!hasSubtitleData())
            {
                return null;
            }
    
            if (!mSrtHelper.hasFoundSrt)//初始状态下为false,seekto之后为false
            {
                Srt srt = mSrtList.get(mSrtHelper.current);
    
                while (srt != null && currentPosition >= 0
                        && srt.getEndTime() < currentPosition)
                {
                    mSrtHelper.current++;
    
                    srt = mSrtHelper.current < mSrtHelper.srtSize ? mSrtList
                            .get(mSrtHelper.current) : null;
                }
    
                mSrtHelper.hasFoundSrt = true;
                mNextSrt = getNextSrt(mSrtHelper.current);//保存下个srt文件
            }
            else if (mNextSrt != null)
            {
                if (currentPosition >= mNextSrt.getStartTime())//当前时间已经到超过下个srt,更新当前srt 和 nextSrt
                {
                    mSrtHelper.current++;
                    mNextSrt = getNextSrt(mSrtHelper.current);
                }
                else if (currentPosition > mNextSrt.getEndTime())
                {
                    mSrtHelper.hasFoundSrt = false;
                }
            }
            return mSrtList.get(mSrtHelper.current);
        }



  • 相关阅读:
    常见的排序算法(四):归并排序
    常见的排序算法(三):快速排序
    常见的排序算法(二):选择排序
    a标签没有闭合引起自动插入很多a标签的问题
    js笔记
    Vue笔记
    CSS笔记
    bootstrap--网格化布局
    backgroud图片充满元素的方法
    bootstrap--概述
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2989551.html
Copyright © 2011-2022 走看看