編輯:關於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);
}
針對Android Studio的系列文章,都是一個小問題為一篇,並沒有整理到一起,主要是方便大家根據自己的需要來查找,同時為了便於大家理解,都會直接上圖。 我這裡使用的
TextPaint是paint的子類,用它可以很方便的進行文字的繪制,一般情況下遇到繪制文字的需求時,我們一般用TextPaint所提供的方法。開始學習如何繪制文字之前,
今天有一個Android新手使用strings.xml進行格式化的時候報了占位符錯誤, Multiple substitutions specified in non-
首先apk不能被代碼混淆(或未經編譯優化),如果混淆了,反編譯出來的代號還是看不懂, 當然,在你沒反編譯出來之前,你也不知道有沒有混淆。 網上各種反編譯工具,&