之前說了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); }