`

player1225change

 
阅读更多
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()" />
				&nbsp; <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()" />
			&nbsp;&nbsp;&nbsp;
			<input type="button" value="download" onclick="downloadRawText()" />
			&nbsp;&nbsp;&nbsp;
			<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>


分享到:
评论

相关推荐

    player0109change

    NULL 博文链接:https://zgq456.iteye.com/blog/2174472

    百度apollo lane_change_decider 详细注释代码

    百度apollo lane_change_decider 详细注释代码

    Android代码-Music Player

    You can sort the tracks by the Title or Artist, as well as change the Equalizer. Does not yet support filtering by artist or album, stay tuned! It contains a widget with customizable text color, ...

    Change default media player-crx插件

    此扩展程序更改了Chrome中的默认媒体播放器。 新播放器提供了更舒适的控制面板以供使用。 此扩展程序更改了Chrome中的默认纯媒体播放器。 新播放器提供了更舒适的控制面板以供使用。 语言:English

    Registry_Manager.rar_The Change Function_Windows 7 Registry

    Source code of registry manager.... 4)Change the Title of Windows Media Player. 5)Remove Recent Documents from the Start Menu. 6)Hide the Taskbar Clock. 7)Remove Username from the Start Menu.

    tb-video-player:淘宝视频播放器KISSY组件

    tb-video-player 版本:1.5 教程: demo: changelog V1.5 修复一个页面上有多个播放器同时存在引起的bug; V1.4 增加两个方法:play和pause,支持js处理播放器的播放和暂停; 修复一个拼写错误,万万不该,destroy...

    GUI-Web-Music-Player:具有易于使用的 GUI 的在线音乐播放器

    GUI Web Player An Easy to use Music ... him, and access for the family at home to change and start music from anywhere in the house. ----------------------------------------------------------------

    worst-player-award

    最差球员奖 使用Angular 2的示例应用程序 Warning : Angular 2.0 is not production ...# change directory to our repo cd worst-player-award # then open your browser and go to http://localhost:3000 npm start

    Web-Based-Radio-Player:基于Web技术的简单,有效的Windows广播播放器-停产

    基于网络的广播播放器 • • • :page_facing_up: 说明 用于基于Windows技术的Windows的简单但有效的广播播放器-停产...- Fixed: Player refresh. v1.0: First Release. :copyright: 版权 :copyright:克里斯蒂安

    :tangerine:克莱门汀音乐播放器-C/C++开发

    最新版本最新预发布网站:http://www.clementine-player.org/ Github:https://github.com/clementine-player/Clementine打开问题要求新功能请:检查新功能尚未实现(Changelog)检查其他人是否尚未打开问题。...

    amrnb 播放本地amr音频文件

    准备插件:amrnb.min.js,pcmdata.min... document.getElementById('file').addEventListener('change', function(evt) { var f = evt.target.files[0]; // File Object handleFileSelect(f); }, false); &lt;/html&gt;

    智能影院Smart Movie 破解版for syban s60 v5

    06. Friendly PC converter - preview videos on PC, select parts you want to convert, change conversion quality 07. Converter supports DirectShow codecs, so you may use video codecs downloadable from ...

    QPlayer左下角悬浮多功能mp3音乐播放器插件

    var playlist = [ {title:"木小雅",artist:"可能否", mp3:"Player/木小雅+-+可能否....function bgChange(){ var lis= $('.lib'); for(var i=0; i; i+=2) lis[i].style.background = 'rgba(246, 246, 246, 0.5)'; }

    SmoothMoves

    Unity3D 插件。2D骨骼动画。可将2D图像转换成Unity皮肤化网格等。 Features: •Create projects with smooth 2D animations like many popular games ...•Works on PC, Mac, Unity Webplayer, Android, and iOS

    pytmx-collision:pygame pytmx 平铺碰撞检测

    pytmx-碰撞 pygame pytmx 平铺碰撞... 主循环逻辑: If player.direction = "Right" then player.rect.x += change_in_x If player.direction = "Up" then player.rect.x += -change_in_y ##记住,加负数就是减法等等

    三维世界地图

    Almost everything is costomizable in this program,you can change the color of the earth. Now you can run the program in standurd window, fullscreen or transparent window. Main features: Real 3D ...

    crtmpserver源码

    * Change the 127.0.0.1 to either the IP of your crtmpserver or simply use a hostname of your machine * Replace file-download with the actual filename of your sample you download. Remeber to omit the ....

    Android代码-Timber音乐播放器

    [WIP][BETA]-Material Design Music Player Screenshots Features Material design Browse Songs, Albums, Artists Create and edit playlists 6 different now playing styles Homescreen widgets Browse...

    吉林大学软件学院卓班设计模式第三次练习

    6: Change To EF 0: Exit Your selected: 也可能在菜单显示时,循环播放背景音乐,离开菜单时,停止播放。 现将Menu中的Process改为virtual,通过复用已有的各Menu,给Menu增加一些额外的功能。请使用装饰模式...

    Android代码-MediaLoader

    MediaLoader allow you to enable cache video/audio while playing for any android media player with single line code. Features caching to disk while streaming,no wait; offline work with cached data,no ...

Global site tag (gtag.js) - Google Analytics