PlayerServlet
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import player.LrcBean;
import com.google.gson.Gson;
/**
* Servlet implementation class PlayerServlet
*/
@WebServlet(urlPatterns = "/play.do", asyncSupported = true)
public class PlayerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String SPLIT_TOKEN = "|||";
/**
* @see HttpServlet#HttpServlet()
*/
public PlayerServlet() {
super();
}
public String getLrcNameFromSrc(String srcName) {
if (StringUtils.isEmpty(srcName)) {
return "";
}
return srcName.substring(srcName.lastIndexOf("/") + 1,
srcName.lastIndexOf("."))
+ ".txt";
}
public int getSecondsInt(String timeStr) {
if (timeStr.length() == 5) {
timeStr = "00:" + timeStr;
}
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = null;
try {
date = dateFormat.parse(timeStr);
} catch (ParseException e) {
e.printStackTrace();
}
long seconds = date.getTime() / 1000L;
return (int) seconds;
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected synchronized void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String remoteAddr = request.getRemoteAddr();
System.out.println("###doPost### date:" + new Date() + " remoteAddr:" + remoteAddr);
String action = request.getParameter("action");
String name = request.getParameter("name");
String startStr = request.getParameter("start");
String endStr = request.getParameter("end");
String textStr = request.getParameter("text");
String lastUptStr = request.getParameter("lastUpt");
if (StringUtils.isEmpty(textStr)) {
textStr = " ";
}
textStr = StringUtils.replace(textStr, "\r", " ");
textStr = StringUtils.replace(textStr, "\n", " ");
name = getLrcNameFromSrc(name);
System.out.println("action:" + action + " startStr:" + startStr
+ " endStr:" + endStr + " textStr:" + textStr);
System.out.println("name:" + name);
File lrcDir = new File("lrcDir");
if (!lrcDir.exists()) {
lrcDir.mkdirs();
}
File lrcFile = new File(lrcDir, name);
if ("add".equals(action)) {
String msg = "0";
int start = getSecondsInt(startStr);
int end = getSecondsInt(endStr);
List<String> lineList = new ArrayList<String>();
if (lrcFile.exists()) {
lineList = FileUtils.readLines(lrcFile);
}
System.out.println("###lrcDir:" + lrcDir.getAbsolutePath());
StringBuilder sb = new StringBuilder();
String lastestUptStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date());
String lineInfo = start
+ SPLIT_TOKEN
+ end
+ SPLIT_TOKEN
+ textStr
+ SPLIT_TOKEN
+ lastestUptStr
+ SPLIT_TOKEN + remoteAddr;
boolean matched = false;
for (int i = 0; i < lineList.size(); i++) {
String oneLine = lineList.get(i);
if (StringUtils.trim(oneLine).isEmpty()) {
continue;
}
String[] fieldsArr = StringUtils.split(oneLine, SPLIT_TOKEN);
// update data
if (fieldsArr[0].equals(start + "")) {
if(!oneLine.contains(SPLIT_TOKEN + lastUptStr)) {
msg = "-1";
}
oneLine = lineInfo;
matched = true;
}
// insert data
if (!matched && Integer.parseInt(fieldsArr[0]) > start) {
matched = true;
sb.append(lineInfo + "\r\n");
}
sb.append(oneLine + "\r\n");
}
if (lineList.size() == 0 || !matched) {
sb.append(lineInfo + "\r\n");
}
if("0".equals(msg)) {
FileUtils.writeStringToFile(lrcFile, sb.toString());
FileUtils.writeStringToFile(new File(lrcDir, "historyLog_" + name), lineInfo + "\r\n", true);
}
response.setContentType("application/json");
Gson gson = new Gson();
response.getWriter().print(gson.toJson(new String[]{msg, lastestUptStr}));
response.getWriter().close();
} else if ("getLrcList".equals(action)) {
List<String> lineList = new ArrayList<String>();
List<LrcBean> lrcBeanList = new ArrayList<LrcBean>();
if (lrcFile.exists()) {
lineList = FileUtils.readLines(lrcFile);
}
for (int i = 0; i < lineList.size(); i++) {
String oneLine = lineList.get(i);
if (StringUtils.trim(oneLine).isEmpty()) {
continue;
}
String[] fieldsArr = StringUtils.split(oneLine, SPLIT_TOKEN);
LrcBean lrcBean = new LrcBean(fieldsArr[0], fieldsArr[1],
fieldsArr.length <= 2 ? ""
: (StringUtils.isBlank(fieldsArr[2]) ? ""
: fieldsArr[2]), fieldsArr[3]);
lrcBeanList.add(lrcBean);
}
response.setContentType("application/json");
Gson gson = new Gson();
response.getWriter().print(gson.toJson(lrcBeanList));
response.getWriter().close();
} else if ("downloadLrc".equals(action)) {
if (!lrcFile.exists()) {
FileUtils.writeStringToFile(lrcFile, "");
}
response.setHeader("Content-disposition", "attachment; filename="
+ lrcFile.getName());
BufferedInputStream buffInput = new BufferedInputStream(
new FileInputStream(lrcFile.getAbsolutePath()));
BufferedOutputStream buffout = new BufferedOutputStream(
response.getOutputStream());
int length = -1;
byte[] buff = new byte[1024];
while ((length = buffInput.read(buff)) != -1) {
buffout.write(buff, 0, length);
}
buffout.flush();
buffInput.close();
buffout.close();
} else if ("getAudioList".equals(action)) {
String rootPath = getServletConfig().getServletContext()
.getRealPath("/");
File audioDir = new File(rootPath + "/audio");
response.setContentType("application/json");
Gson gson = new Gson();
response.getWriter().print(gson.toJson(audioDir.list()));
response.getWriter().close();
} else if ("fetchRawMsg".equals(action)) {
String fileContent = "N/A";
if (lrcFile.exists()) {
fileContent = FileUtils.readFileToString(lrcFile);
}
response.getWriter().print(fileContent);
response.getWriter().close();
} /*else if ("saveRawMsg".equals(action)) {
String fileContent = request.getParameter("content");
FileUtils.writeStringToFile(lrcFile, fileContent);
response.getWriter().print("save successfully");
response.getWriter().close();
}*/
}
}
functions.js
var currAudio;
var duration = 30;
var timer ;
var initTimer ;
var currentAudioSrc = "";
function Init() {
$.ajax({
type : "POST",
url : "play.do",
data : {
action : 'getLrcList',
name : currentAudioSrc
},
async:false,
dataType : "json",
success : function(data) {
// alert(data);
for(var i = 0; i < data.length; i++) {
addDetail(data[i].start, data[i].end, data[i].text, data[i].lastUpt, null, true);
}
}
});
var startVar = 0;
var endVar = 0;
if ($("#tblData tr").length == 1) {
startVar = 0;
endVar = duration;
addDetail(startVar, endVar, null, null, null, false);
}
}
//<img src='images/delete.png' class='btnDelete'/>
function addDetail(startVar, endVar, text, lastUpt, baseRow, saved) {
var baseObj;
if(typeof (text) == "undefined" || text == null) {
text = "";
}
var trInfo = "<tr>"
+ "<td><span name='numSpan'>1</span></td>"
+ "<td>"
+ conversionTime(startVar)
+ "</td>"
+ "<td><span>"
+ conversionTime(endVar)
+ "</span><div><input type='button' value='split' onclick='mysplit(this)' /></div></td>"
+ "<td><textarea class='textareaText' rows='5' cols='10' onkeyup='taChange(this)'>" + text + "</textarea></td>"
+ "<td><img src='images/play.JPG' class='btnPlay' onclick='playSeg(this)'><img src='images/save" + (saved ? "d" : "") + ".png' class='btnSave' onclick='Save(this)'>"
+ "<input type='hidden' name='lastUpt' value='" + lastUpt + "'"
+ "</td>"
+ "</tr>";
if (typeof (baseRow) == "undefined" || baseRow == null) {
baseObj = $("#tblData tbody");
baseObj.append(trInfo);
} else {
baseObj = baseRow;
baseObj.after(trInfo);
}
// $(".btnSave").bind("click", Save);
// $(".btnDelete").bind("click", Delete);
// var numSpans = document.getElementsByName("numSpan");
// alert("numSpans.length:" + $('[name="numSpan"]').length);
// for(var i = 0; i < numSpans.length; i++) {
// alert(i);
// $(numSpans[i]).html(i + 1);
// }
$.each( $('[name="numSpan"]'), function( key, value ) {
// alert( key + ": " + value );
$(value).html(key + 1);
});
}
$('.textareaText').bind('input propertychange', function() {
taChange(this);
});
function taChange(taObj) {
// alert($(taObj).val());
var saveBtn = $(taObj).parent().next().children(".btnSave");
saveBtn.attr("src", "images/save.png");
}
var lastPlayBtn = null;
var ix = 0;
function playSeg(btn) {
if(lastPlayBtn != null && lastPlayBtn != btn) {
// $(".btnPlay").attr("src", "images/play.JPG");
$(lastPlayBtn).attr("src", "images/play.JPG");
}
//var currBtnSrc = $(btn).attr("src");
//$(btn).attr("src", currBtnSrc);
clearInterval(timer);
currAudio.pause();
// alert("here1");
var start;
var end;
// alert("start:" + start + " end:" + end + " currentTime:" +
// currAudio.currentTime);
var startTd = $(btn).parent().prev().prev().prev();
var endTd = $(btn).parent().prev().prev();
var thisTr = startTd.parent().parent();
start = getSeconds(startTd.html());
end = getSeconds(endTd.text());
if ($(btn).attr("src") == "images/play.JPG") {
console.log("here22");
//alert("here2");
setTimeout(function () {
$(btn).attr("src", "images/pause.jpg");
}, 100);
currAudio.currentTime = start;
currAudio.play();
timer = setInterval(function() {
if (currAudio.currentTime > end) {
currAudio.pause();
$(btn).attr("src", "images/play.JPG");
clearInterval(timer);
} else {
// $(btn).attr("src", "images/pause.jpg");
}
}, 1000);
} else {
console.log("here3");
//alert("here3");
$(btn).attr("src", "images/play.JPG");
currAudio.pause();
}
lastPlayBtn = btn;
}
function Save(btn) {
var lastUpt = $(btn).next().val();
console.log("lastUpt:" + lastUpt);
// alert("save btn");
var start;
var end;
var startTd = $(btn).parent().prev().prev().prev();
var endTd = $(btn).parent().prev().prev();
var textTd = $(btn).parent().prev();
var thisTr = startTd.parent().parent();
start = startTd.html();
end = endTd.text();
$.ajax({
type : "POST",
url : "play.do",
data : {
action : 'add',
name : currAudio.currentSrc,
start : start,
end : end,
text : textTd.children(0).val(),
lastUpt : lastUpt
},
dataType : "json",
success : function(data) {
// alert(data);
if(data[0] == "0") {
$(btn).attr("src", "images/saved.png");
$(btn).next().val(data[1]);
} else {
alert("your this row data is dirty, please backup data, refresh page, and try to save again");
}
}
});
}
function Delete() {
var par = $(this).parent().parent(); // tr
par.remove();
}
function mysplit(btn) {
var start;
var end;
var endStr;
var preSpan = $(btn).parent().prev();
var thisTr = preSpan.parent().parent();
start = getSeconds($(btn).parent().parent().prev().html());
end = getSeconds(preSpan.html());
// alert("start:" + start + " end:" + end);
if (currAudio.currentTime > start
&& currAudio.currentTime < end) {
var saveBtn = $(btn).parent().parent().next().next().children(".btnSave");
var playBtn = $(btn).parent().parent().next().next().children(".btnPlay");
saveBtn.attr("src", "images/save.png");
playBtn.attr("src", "images/play.JPG");
preSpan.html(conversionTime(parseInt(currAudio.currentTime)));
addDetail(parseInt(currAudio.currentTime), end, "", "", thisTr);
saveBtn.click();
$(btn).parent().parent().parent().next().children("td:last-child").children(".btnSave").click();
}
}
function back() {
currAudio.currentTime -= 3;
}
// 歌词时间增加2s
function forward() {
currAudio.currentTime += 3;
}
function conversionTime(time){
var surplusHour,
surplusMinite,
surplusSecond,
cTime;
//将剩余秒数转化为分钟
surplusHour = Math.floor(time / 3600);
//将剩余秒数转化为分钟
surplusMinite = Math.floor((time / 60) % 60);
//将剩余秒数转化为秒钟
surplusSecond = Math.floor(time % 60);
if(surplusSecond < 10){
surplusSecond = "0" + surplusSecond;
}
if(surplusMinite < 10){
surplusMinite = "0" + surplusMinite;
}
if(surplusHour < 10){
surplusHour = "0" + surplusHour;
}
cTime = surplusMinite + ":" + surplusSecond;
if(surplusHour != 0) {
cTime = surplusHour + ":" + cTime;
}
return cTime;
}
function getSeconds(timeStr) {
var timeStrArr = timeStr.split(":");
var timeLong = 0;
timeLong += (parseInt(timeStrArr[timeStrArr.length-1]) + parseInt(timeStrArr[timeStrArr.length-2] * 60));
if(timeStrArr.length == 3) {
timeLong += parseInt(timeStrArr[0] * 3600);
}
//alert("timeStr:" + timeStr + " timeLong:" + timeLong);
return timeLong;
}
/*
*函数功能:从href获得参数
*sHref: http://www.artfh.com/arg.htm?arg1=d&arg2=re
*sArgName:arg1, arg2
*return: the value of arg. d, re
*/
function GetArgsFromHref(sHref, sArgName)
{
var args = sHref.split("?");
var retval = "";
if(args[0] == sHref) /*参数为空*/
{
return retval; /*无需做任何处理*/
}
var str = args[1];
args = str.split("&");
for(var i = 0; i < args.length; i ++)
{
str = args[i];
var arg = str.split("=");
if(arg.length <= 1) continue;
if(arg[0] == sArgName) retval = arg[1];
}
return retval;
}
function fetchRawText() {
$("#rawTa").val("");
$.ajax({
type : "POST",
url : "play.do",
data : {
action : 'fetchRawMsg',
name : currentAudioSrc
},
dataType : "text",
success : function(data) {
$("#rawTa").val(data);
}
});
}
function downloadRawText() {
window.location = "play.do?action=downloadLrc&name=" + currentAudioSrc;
}
function saveRawText() {
$.ajax({
type : "POST",
url : "play.do",
data : {
action : 'saveRawMsg',
name : currentAudioSrc,
content : $("#rawTa").val()
},
dataType : "text",
success : function(data) {
alert(data);
window.location = window.location;
}
});
}
function doSearch() {
var fromDate = $("#from").val() + " 00:00:00";
var toDate = $("#to").val() + " 23:59:59";
console.log("fromDate:" + fromDate + " toDate:" + toDate);
$.each( $("#tblData tr"), function( key, value ) {
console.log( key + ": " + value );
if(key != "0") {
var currUptDate = $(value).children().eq(4).children().eq(2).val();
if(currUptDate >= fromDate && currUptDate <= toDate) {
$(value).show();
} else {
$(value).hide();
}
}
// $(value).html(key + 1);
});
}
$(document).ready(function() {
currAudio = document.getElementById("currAudio");
// alert("window.location.href:" + window.location.href);
//alert("source:" + GetArgsFromHref(window.location.href, "source"));
var audioSource = GetArgsFromHref(window.location.href, "source");
if(audioSource == "") {
$("#filenameSpan").html("demo.mp3");
audioSource = "audio/demo.mp3";
} else {
$("#filenameSpan").html(audioSource);
audioSource = "audio/" + audioSource;
}
// alert("audioSource:" + audioSource );
$("#audioSource").attr("src", audioSource).detach().appendTo("#currAudio");
currentAudioSrc = audioSource;
// currAudio.load();
initTimer = setInterval(function() {
// alert("here:" + currAudio.duration + " isNaN:" + !isNaN(currAudio.duration));
if (!isNaN(currAudio.duration)) {
duration = currAudio.duration;
$("#totSec").html(duration);
clearInterval(initTimer);
Init();
}
}, 1000);
$('#currAudio').bind('pause', function () {
$(".btnPlay").attr("src", "images/play.JPG");
});
$( "#from" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 1,
dateFormat : "yy-mm-dd",
onClose: function( selectedDate ) {
$( "#to" ).datepicker( "option", "minDate", selectedDate );
}
});
$( "#to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
dateFormat : "yy-mm-dd",
numberOfMonths: 1,
onClose: function( selectedDate ) {
$( "#from" ).datepicker( "option", "maxDate", selectedDate );
}
});
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title>Fight English</title>
<style type="text/css">
.btnPlay {
width: 30px;
height: 30px;
cursor: pointer;
margin: 2px;
}
.btnSave {
width: 30px;
height: 30px;
cursor: pointer;
margin: 2px;
}
.btnDelete {
width: 30px;
height: 30px;
cursor: pointer;
}
.btnEdit {
width: 30px;
height: 30px;
cursor: pointer;
}
.textareaText {
border: none;
width: 100%;
-webkit-box-sizing: border-box; /* <=iOS4, <= Android 2.3 */
-moz-box-sizing: border-box; /* FF1+ */
box-sizing: border-box; /* Chrome, IE8, Opera, Safari 5.1*/
}
div.ui-input-text { width: 90px !important; }
</style>
</head>
<body>
<div data-role="page" id="pageone" >
<div data-role="header" style="width:100%; position: fixed;background: #2A3758;margin-left: auto;margin-right: auto;">
<center>
<!--audio 是HTML5中的新元素-->
<!-- 20141217Steve.mp3 controls显示那个播放器 autoplay歌曲就绪后自动播放 loop歌曲放完了循环-->
<audio controls id="currAudio" loop="false" style="height: 50px;">
<source id="audioSource" src="">
<p>Your user agent does not support the HTML5 Audio element.</p>
</audio>
<div style="margin: 5px">
<input id="backBtn" type="button" value="back3s" data-inline="true" onclick="back()" />
<input id="forwardBtn" type="button" value="forward3s" data-inline="true"
onclick="forward()" /> <br/> Filename:<span id="filenameSpan"></span> Tip: ?? = unkonwn, #XXX# means not sure
</div>
</center>
</div>
<div data-role="content" style="margin-top: 120px;">
<!-- style="display:none;" -->
<div style="margin: 10px;" >
<label for="from">From</label>
<input type="text" id="from" name="from" />
<label for="to">to</label>
<input type="text" id="to" name="to" />
<input type="button" value="Search" onclick="doSearch()" />
</div>
<table id="tblData" style="width: 95%;border: 1px solid #cccccc; ">
<thead>
<tr>
<th width="10%">No.</th>
<th width="15%">Start</th>
<th width="15%">End</th>
<th width="40%">Text</th>
<th width="10%">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div data-role="footer">
backend storge:
<br/>
<input type="button" value="fetch" onclick="fetchRawText()" />
<input type="button" value="download" onclick="downloadRawText()" />
<span style="display: none;">
<input type="button" value="save" onclick="saveRawText()" />
</span>
<textarea id="rawTa" rows="30" cols="30"></textarea>
</div>
</div>
</body>
</html>
<link rel="stylesheet"
href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css">
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="javascript/jquery-1.8.3.min.js"></script>
<script src="javascript/jquery.mobile-1.3.2.min.js"></script>
<script type="text/javascript" src="javascript/functions.js"></script>
<script type="text/javascript" src="javascript/jquery-ui.js"></script>