スポンサーサイト

 --, -- --:--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

開発日誌 - コメント表示型の動画プレイヤー for Android (XMLを‘再生’する為のクラス群)

 09, 2013 02:02
課題はまだまだ多いですが、とりあえず動画とコメントの再生までは実装できました。

下記は jDOM2 を使って XML ファイルを読み取り、コメントが出現するタイミングでイベント通知を行う為のクラスです。
Activity 側でイベントリスナーをセットして、SurfaceView のコメントを画面上に流します。

コメントファイルはコメントのタイミングをミリ秒単位で記録されていますが、今回このクラスのイベント通知は 1 秒単位に設定してあります。


### XmlReader.java
package com.example.xml;

import java.io.File;
import java.util.Comparator;
import java.util.List;
import java.util.Timer;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import android.content.Context;

// コメントファイルリーダー
public class XmlReader implements Runnable {

private String _path;
private List<Element> _comments;
private int _pointer;
private Context _context;
private Timer _timer;
private long _time;
private XmlReadEventListener _listener;
private boolean _isPrepared;
private Thread _thread;
private XmlTask _task;

public XmlReader(Context context, String path) {
_context = context;
_path = path;
_pointer = 0;
_isPrepared = false;
}

// XMLを開く
public void open() {
_thread = new Thread(this);
_thread.start();
}

// XMLを閉じる
public void close() {
_path = null;
_thread = null;
}

// XMLを再生する
public void play() {
_timer = new Timer();
_task = new XmlTask(_comments, _listener);
_task.setTime(_time);
_task.setPointer(_pointer);
_timer.schedule(_task, 0, 1000);
}

// 再生を一時停止する
public void pause() {
_task.cancel();
_pointer = _task.getPointer();
_time = _task.getTime();
_task = null;
_timer = null;
}

// 再生を中断する
public void stop() {
_task.cancel();
_time = 0;
_pointer = 0;
_task = null;
_timer = null;
}

// 再生位置を移動する
public void seekTo(long time) {
pause();
_time = time / 1000;
_pointer = shiftPointer(_pointer, time);
play();
}

// 現在の再生時間を取得する
public long getTime() {
return _task.getTime();
}

// XMLファイルが開かれているか
public boolean isPrepared() {
return _isPrepared;
}

// イベントリスナー登録
public void setXmlReadEventListener(XmlReadEventListener listener) {
_listener = listener;
}

// 再生位置を求める
private int shiftPointer(int point, long targetTime) {
Element comment;
String time;

if (point >= _comments.size()) {
point = _comments.size() - 1;
}

comment = _comments.get(point);
time = comment.getAttribute("vpos").getValue();
int skip = (int)Math.ceil(((double)_comments.size()) / 100);

if (Long.valueOf(time) < targetTime / 10) {
while (_comments.size() - 1 > point && Long.valueOf(time) < targetTime / 10) {
point += skip;
comment = _comments.get(point);
time = comment.getAttribute("vpos").getValue();
}
point += skip;
} else {
do {
point -= skip;
if (point < 0) {
point = 0;
break;
}
comment = _comments.get(point);
time = comment.getAttribute("vpos").getValue();
} while (0 <= point && Long.valueOf(time) > targetTime / 10);
}

return point;
}

@Override
// ファイルオープン処理(スレッド)
public void run() {

Document doc;
Element root;

try {
File file = new File(_path);
if (file.exists()) {
doc = new SAXBuilder().build(file);
root = doc.getRootElement();
root.sortChildren(new XmlComparator());
_comments = root.getChildren("chat");
_isPrepared = true;
if (_listener != null) _listener.onReadCompleted(_context, true, _comments.size());

} else {
_isPrepared = false;
if (_listener != null) _listener.onReadCompleted(_context, false, 0);

}
} catch (Exception e) {
e.printStackTrace();
_isPrepared = false;
if (_listener != null) _listener.onReadCompleted(_context, false, 0);
} finally {
doc = null;
root = null;
}
}

// ソート用クラス
public class XmlComparator implements Comparator<Element> {
public int compare(Element a, Element b) {
if (a.getName().contains("chat") && b.getName().contains("chat")){
return Integer.parseInt(a.getAttribute("vpos").getValue()) - Integer.parseInt(b.getAttribute("vpos").getValue());
} else {
return 0;
}
}
}
}


### XmlTask.java
package com.example.xml;

import java.util.List;
import java.util.TimerTask;
import org.jdom2.Element;
import android.os.Handler;

// リーダーに1秒毎に呼び出されるタスク
public class XmlTask extends TimerTask {

private Handler _handler;
private long _time;
private List<Element> _comments;
private int _pointer;
private XmlReadEventListener _listener;

public XmlTask(List<Element> comments, XmlReadEventListener listener) {
_comments = comments;
_time = 0;
_pointer = 0;
_handler = new Handler();
_listener = listener;
}

// 再生処理(スレッド)
public void run() {

_handler.post(new Runnable() {
@Override
public void run() {
if (_comments.size() > _pointer) {
Element comment;
String time;

while (_listener != null && _comments.size() > _pointer) {
comment = _comments.get(_pointer);
time = comment.getAttribute("vpos").getValue();

if (_time < (Integer.valueOf(time) / 100)) break;
if (_listener != null && (_time - (Integer.valueOf(time) / 100)) <= 1) _listener.onTime(comment.getValue());

_pointer++;
}
_time++;
}
}
});
}

// 現在の再生時間を取得
public long getTime() {
return _time;
}

// 現在の再生時間を設定
public void setTime(long time) {
_time = time;
}

// XML読み込み位置を取得
public int getPointer() {
return _pointer;
}

// XML読み込み位置を設定
public void setPointer(int pointer) {
_pointer = pointer;
}
}


### XmlReadEventListener.java
package com.example.xml;

import java.util.EventListener;
import android.content.Context;
import android.os.Handler;

// イベント通知用クラス
public class XmlReadEventListener implements EventListener {

private Context _context;
private Handler _handler;
private int _commentCount;

public XmlReadEventListener(Context context) {
_context = context;
_handler = new Handler();
}

// XMLファイル読み込み完了通知
public void onReadCompleted(Context context, boolean result, int commentCount) {
_commentCount = commentCount;
}

// コメント表示タイミング通知
public void onTime(String comment) {
}

// ハンドル取得
protected Handler getHandler() {
return _handler;
}

// コンテキスト取得
protected Context getContext() {
return _context;
}

// コメント総数取得
protected int getCommentCount() {
return _commentCount;
}
}


結構なメモリ食いなので、後々軽量化していきます...



関連記事
開発日誌 - コメント表示型の動画プレイヤー for Android
開発日誌 - コメント表示型の動画プレイヤー for Android (流れるコメントクラスの実装)
開発日誌 - コメント表示型の動画プレイヤー for Android (コメント速度の計算)
開発日誌 - コメント表示型の動画プレイヤー for Android (アイコン作成)
開発日誌 - コメント表示型の動画プレイヤー for Android (とりあえずそれっぽくなった)


スポンサーサイト

Tag:Android 動画 プレイヤー Eclipse コメント java jDOM2 XML

COMMENT - 0



WHAT'S NEW?

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。