Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android MediaPlayer 字幕同步

Android MediaPlayer 字幕同步

編輯:關於Android編程

大致思想如下:

從網上獲取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文件網上很蠻多的介紹,大家可以搜索下。
我是這樣解析的:
[java] 
<SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 12px"> 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();</SPAN> 

 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文件,然後顯示。
這個方法不斷的被調用..
[html]
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); 
            } 
        } 
    } 

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);
            }
        }
    }


[java] 
<SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 12px">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); 
    }</SPAN> 

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);
    }

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved