一,VideoJS介绍

  1. 引用脚本,videojs很为你着想,直接cdn了,你都不需要下载这些代码放入自己的网站

    1. <link href=”http://vjs.zencdn.net/c/video-js.css” rel=”stylesheet”>
    2. <script src=”http://vjs.zencdn.net/c/video.js”></script>
  2. 如果需要支持IE8,这个js可以自动生成flash

    1. <!-- If you'd like to support IE8 -->
    2. <script src="http://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
  3. 页面中加入一个Html5的video标签

    1. <video id="my_video_1" class="video-js vjs-default-skin"
    2. controls preload="auto" width="640" height="264" poster="my_video_poster.png" data-setup="{}">
    3. <source src="my_video.mp4" type="video/mp4">
    4. <source src="my_video.webm" type="video/webm">
    5. </video>

其中post就是视频的缩略图,那俩source一个指向mp4视频,一个指向webm视频,在页面加载过程中,video.js会判断浏览器支持哪个格式视频,会自动加载可播放的视频。 
简单吧!

进阶:使用api

获取对象: 
后面那个就是就是video标签的id值,这是myPlayer就是播放器对象了。

  1. videojs("my-video").ready(function(){
  2. window.myPlayer = this;
  3. // EXAMPLE: Start playing the video.
  4. myPlayer.play();
  5. });

方法:

获取对象

var videoObj = videojs(“videoId”);

ready:

  1. myPlayer.ready(function(){
  2. //在回调函数中,this代表当前播放器,
  3. //可以调用方法,也可以绑定事件。
  4. })

播放:

  1. myPlayer.play();

暂停:

  1. myPlayer.pause();

获取播放进度:

  1. var whereYouAt = myPlayer.currentTime();

设置播放进度:

  1. myPlayer.currentTime(120);

视频持续时间,加载完成视频才可以知道视频时长,且在flash情况下无效

  1. var howLongIsThis = myPlayer.duration();

缓冲,就是返回下载了多少

  1. var whatHasBeenBuffered = myPlayer.buffered();

百分比的缓冲

  1. var howMuchIsDownloaded = myPlayer.bufferedPercent();

声音大小(0-1之间)

  1. var howLoudIsIt = myPlayer.volume();

设置声音大小

  1. myPlayer.volume(0.5);

取得视频的宽度

  1. var howWideIsIt = myPlayer.width();

设置宽度:

  1. myPlayer.width(640);

获取高度

  1. var howTallIsIt = myPlayer.height();

设置高度:

  1. myPlayer.height(480);

一步到位的设置大小:

  1. myPlayer.size(640,480);

全屏

  1. myPlayer.enterFullScreen();

离开全屏

  1. myPlayer.enterFullScreen();

添加事件

  1. durationchange
  2. ended //播放结束
  3. firstplay
  4. fullscreenchange
  5. loadedalldata
  6. loadeddata
  7. loadedmetadata
  8. loadstart
  9. pause //暂停
  10. play //播放
  11. progress
  12. seeked
  13. seeking
  14. timeupdate
  15. volumechange
  16. waiting
  17. resize inherited
  18. var myFunc = function(){
  19. // Do something when the event is fired
  20. };

事件绑定

  1. myPlayer.on("ended", function(){
  2. console.log("end", this.currentTime());
  3. });
  4. myPlayer.on("pause", function(){
  5. console.log("pause")
  6. });

删除事件

  1. myPlayer.removeEvent(“eventName”, myFunc);

虽然文章说明在不支持html5的情况下,会以flash播放,但在支持html5的firefox下播放mp4时,却遇到很大的困难,虽然调用了flash,但一直无法播放(不过我也一直怀疑我的firefox下的flash有问题,不知道是不是真的)。不过如果你听从videojs的建议,放两个格式的视频,就不会有这个问题了。

另外video的写法中还有专门针对flash的写法,当然你也可以用这个插件实现纯粹的flash播放(只写flash那部分就好,可以保证统一的浏览效果,不过iOS的浏览器不兼容flash,这就要你自己进行判断来处理

二、Audio标签介绍

javascript动态创建audio标签

在页面中添加audio元素的方法主要是两种,一种是在html中加入audio代码,可以加入一些属性(autoplay,preload)等,这些在之前的文章已经说过了。另外一种是js动态加载进来的。代码如下:

var audio=document.creatElement(“audio”);
audio.src=”audio/source.ogg”;//路径
audio.play();

或者更简单一些
audio=new Audio(“audio/source.ogg”);//路径
audio.play();

另外audio的属性,preload有三种不同的载入方式,我们可以通过preload=”auto”来实现音频的自动加载,但是我们无法通过直观的方式了解音频加载的进度,以及是否准备播放。这里提供了一个“canplaythrough”事件来监听音频是否已经加载完成。代码示例如下:

  1. <!DOCTYPE html >
  2. <html lang="en">
  3. <head>
  4. <title>Preload Ready</title>
  5. <script type="text/javascript">
  6. var audio = document.createElement("audio");
  7. audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
  8. audio.addEventListener("canplaythrough", function () {
  9. alert('音频文件已经准备好,随时待命');
  10. }, false);
  11. </script>
  12. </head>
  13. <body>
  14. </body>
  15. </html>

运行代码复制代码另存代码(提示:可以编辑后运行)

第一次运行时间会长一些,第二次运行由于文件已经缓存到本地,所以会直接弹出提示框。

javascript控制audio的播放,暂停,停止

js如何控制audio标签的播放比较简单,在上面好多案例中已经提到了。主要是audio.play();同样暂停也比较简单audio.pause();就能很轻易搞定,看到这里你估计以为想要停止的话,也会使用这种语义化的函数了,呵呵,其实不是这样的audio.stop()并不能停止audio的播放。

如果你需要停止或者重新播放audio,必须设置它的currentTime,可见如下语句:

audio.currentTime = 0;

下面我给出一个完成的示例,包括了开始播放,暂停播放,停止播放

  1. <!DOCTYPE html >
  2. <html lang="en">
  3. <head>
  4. <title>Preload Ready</title>
  5. <script type="text/javascript">
  6. var audio = document.createElement("audio");
  7. audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
  8. audio.addEventListener("canplaythrough",
  9. function() {
  10. alert('音频文件已经准备好,随时待命');
  11. },
  12. false);
  13. function aPlay() {
  14. audio.play();
  15. }
  16. function aPause() {
  17. audio.pause();
  18. }
  19. function aStop() {
  20. audio.currentTime = 0;
  21. audio.pause();
  22. }
  23. function aSkip() {
  24. audio.currentTime = 50;
  25. audio.play();
  26.  }
  27. </script>
  28. </head>
  29. <body>
  30. <input type="button" onclick="aPlay();" value="播放音频">
  31. <input type="button" onclick="aPause();" value="暂停音频">
  32. <input type="button" onclick="aStop();" value="停止音频">
  33. <input type="button" onclick="aSkip();" value="跳到第50秒">
  34. </body>
  35. </html>

运行代码复制代码另存代码(提示:可以编辑后运行)

注意:以上代码中的停止加上了pause(),另外跳到50秒加上了play()。这里主要是因为一旦play开始运行无法停止的,所以需要设置currentTime后使得音频暂停。另外跳转到50秒后,加上play()的做法是如果音频在没有播放的情况下,跳转到50秒时音频不会自动播放;而如果音频在播放中,那么跳到50秒的时候还是播放的,这里的play()可以忽略。当然具体情况可以自行定义。

javascript控制audio的声音大小:

控制声音的大小比较简单,大概同play,pause那一套一样,主要是多了一个参数。

示例:audio.volume = 0;//表示静音  audio.volume = 1; 表示声音最大 ,声音值可以取0-1之间

演示不写了,可以自己修改上面代码运行框中的内容。

javascript控制audio的快进,快退,以及显示进度与时长

控制快进,快退的原理比较简单,只不过是设置audio的currentTime,案例如下

比如:audio.currentTime += 10;//10秒快进

  1. <!DOCTYPE html >
  2. <html lang="en">
  3. <head>
  4. <title>Preload Ready</title>
  5. <script type="text/javascript">
  6. var audio = document.createElement("audio");
  7. audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
  8. audio.addEventListener("canplaythrough",
  9. function() {
  10. alert('音频文件已经准备好,随时待命');
  11. },
  12. false);
  13. function aPlay() {
  14. audio.play();
  15. }
  16. function go() {
  17. audio.currentTime += 10;
  18. audio.play();
  19. }
  20. function back() {
  21. audio.currentTime -= 10;
  22. audio.play();;
  23. }
  24. </script>
  25. </head>
  26. <body>
  27. <input type="button" onclick="aPlay();" value="播放音频">
  28. <input type="button" onclick="go();" value="快进10秒">
  29. <input type="button" onclick="back();" value="快退10秒">
  30. </body>
  31. </html>

运行代码复制代码另存代码(提示:可以编辑后运行)

关于显示进度的方法也不是很复杂,不过如果你想实现js配合css做一个进度条的模拟也许复杂一点。如果你对js以及css比较熟悉的话,解决的思路有很多。甚至可以做出很多酷炫的效果。我在这里只是点一下如何调用出该音频文件的时长以及播放到进度的时间。

调用出音频的时长不难解决 “audio.duration;” 就是了

调用处该文件的播放进度,这里需要用到一个时间监听。currentTime代表当前播放的时间,而且当currentTime改变的时候会触发timeupdate事件。因此,我们监听timeupdate,并且输出currentTime即可完成进度的判断。不多说,看示例代码:

  1. <!DOCTYPE html >
  2. <html lang="en">
  3. <head>
  4. <title>Preload Ready</title>
  5. <script type="text/javascript">
  6. var audio = document.createElement("audio");
  7. audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
  8. audio.addEventListener("canplaythrough",
  9. function() {
  10. alert('音频文件已经准备好,随时待命');
  11. },
  12. false);
  13. audio.addEventListener("timeupdate", showtime, true);
  14. function showtime() {
  15. document.getElementById("ltime").innerHTML = audio.duration;
  16. document.getElementById("ctime").innerHTML = audio.currentTime;
  17. }
  18. function aPlay() {
  19. audio.play();
  20. }
  21. function go() {
  22. audio.currentTime += 10;
  23. audio.play();
  24. }
  25. function back() {
  26. audio.currentTime -= 10;
  27. audio.play();
  28. }
  29. </script>
  30. </head>
  31. <body>
  32. 总时长:
  33. <div id="ltime">
  34. </div>
  35. <br/>
  36. 当前播放:
  37. <div id="ctime">
  38. </div>
  39. <br/>
  40. <input type="button" onclick="aPlay();" value="播放音频">
  41. <input type="button" onclick="go();" value="快进10秒">
  42. <input type="button" onclick="back();" value="快退10秒">
  43. </body>
  44. </html>

运行代码复制代码另存代码(提示:可以编辑后运行)

OK,基本的操作已经说完了。

最后留下参考资料给大家:
http://msdn.microsoft.com/zh-CN/ie/hh377903
https://wiki.mozilla.org/Audio_Data_API
http://msdn.microsoft.com/en-us/library/gg589489(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/gg589528(v=vs.85).aspx

三、VideoJS+Audio标签实现视频与音频同步播放

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Online Player</title>
<%@ include file="pages/common/include.jsp"%>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link rel="stylesheet" type="text/css" href="${basePath }css/mobile.css"/>
<link rel="stylesheet" type="text/css" href="${basePath }css/index.css"/>
<link rel="stylesheet" type="text/css" href="${basePath }images/icons/iconfont.css"/>
<script type="text/javascript" src="${basePath }scripts/rem.js"></script>
<!--VideoJS的引用文件-->
<link href="${basePath }jslib/videoJS/video-js.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="${basePath }jslib/videoJS/video.js"></script>
<script>
videojs.options.flash.swf = "${basePath }jslib/videoJS/video-js.swf";
</script>
<script type="text/javascript">
var player;
//加载视频
$(function() {
player = videojs('video');
var audio=new Audio(vt.basePath+"videos/${video.videoSubtitlePath}");//路径

// 开始或恢复播放
player.on('play', function() {
audio.play();
console.log('开始/恢复播放');
});

// 暂停播放
player.on('pause', function() {
audio.pause();
console.log('暂停播放');
});

//调整音量
player.on('volumechange', function() {
audio.volume = player.volume();
console.log('调整音量');
});

//视频跳转
player.on('seeked', function() {
audio.currentTime = player.currentTime();
console.log('改变时长');
});

// 检测播放时间
player.on('timeupdate', function () {
//播放结束
if (player.duration() != 0 && player.currentTime() == player.duration()) {
audio.currentTime = 0;
audio.pause();
console.log('播放结束');
}
var beginTime = 0;
var endTime = 0;
var currentTime = player.currentTime() * 1000;
$("#playerShow p").each(function(){
beginTime = $(this).attr("beginTime");
endTime = $(this).attr("endTime");
if(currentTime>beginTime && currentTime<endTime){
$(this).siblings("p").removeClass("fontStyle");
$(this).addClass("fontStyle");
var oHeight = $('#myCaptions').height();
var tmp = $(this).next().offset().top-$(this).parent().offset().top - oHeight*0.5;
tmp = tmp > 0 ? tmp * -1 : 0;
//$(this).animate($(this).parent()[0]).animate({marginTop: tmp + 'px'}, 500);
$(this).parent().animate({marginTop: tmp + 'px'}, 300);
}
});
});
});

//点击字幕修改
function revise(obj){
//暂停播放
thePlayer.play(false);
//弹出点击字幕及输入框
$('.shak').slideDown(500);
$('.revise .reviseMain') .addClass("animationActive")
//点击字幕时获得每段字幕的开始时间的毫秒值
var beginTime = $(obj).attr("beginTime")/1000;
$("#beginTimeForSeek").val(beginTime);
$("#subtitleId").val($(obj).attr("id"));
$("#oneSrtBody").html($(obj).attr("oneSrtBody"));
var otherSrtBody = $(obj).attr("otherSrtBody")
if(otherSrtBody){
$("#otherSrtBody").html(otherSrtBody);
}
}

//点击输入后确认发送
function saveRevise(){
var reviseContent = $("#reviseContent").val();
if($.string.isNullOrEmpty(reviseContent)){
alertWarn("请输入修正内容!");
return;
}
var data = getFormData("saveRevise");
$.ajax({
type: "POST",
url: vt.basePath+"saveRevise",
data: data,
success:function (result) {
if (result = "1") {
alertInfo("修订已保存成功!", hideRevise);
} else {
alertWarn("修订保存失败!");
}
}
});
}

//隐藏输入框
function hideRevise(){
var beginTime = $("#beginTimeForSeek").val();
thePlayer.seek(beginTime);
$('.shak').hide();
$('.revise .reviseMain') .removeClass("animationActive");
$("#reviseContent").val("");
layer.closeAll("dialog");
}

/**
*显示修正记录
*/
function proofRecord(videoId){
var layerObject = layer.load('加载中');
$.ajax({
type: "POST",
url: vt.basePath+"getRevisedSubtitle",
data: {"videoId":videoId},
success:function (data) {
fillFormByTpl(data, "reviseRecordTpl", "reviseRecord");
layer.close(layerObject);
}
});
}
</script>

<script type="text/html" id="reviseRecordTpl">
{{#
var len = d.length;
for(var i=0; i<len; i++){
}}
<li>
<div class="theLiLfet">{{d[i].beginTimeStr.substring(0, 8)}}</div>
<div class="theLiRight">
<div class="translateAll">
<p class="translateForm">{{d[i].oneSrtBody}}</p>
{{# if(!$.string.isNullOrEmpty(d[i].otherSrtBody)){ }}
<p class="translateTo">{{d[i].otherSrtBody}}</p>
{{# } }}
</div>
{{#
var subtitleReviseList = d[i].subtitleReviseList;
var len1 = subtitleReviseList.length;
for(var j=0; j<len1; j++){
var srcBody = subtitleReviseList[j].srtBody;
}}
<div class="translate">{{srcBody}}</div>
{{# } }}
</div>
<div style="clear:both;"></div>
</li>
{{# } }}
</script>
</head>
<body ondblclick="return false;">
<header>
<a href="javascript:history.go(-1)" class="iconfont icon-fanhui"></a>
<span>电影字幕翻译较对</span>
</header>
<section>
<div id="myElement">
<video id="video" class="video-js vjs-default-skin vjs-big-play-centered"
controls preload="auto" width="100%" height="250px"
poster="${basePath}videos/${video.videoFirstThumbPath}" data-setup='{"example_option":true}'>
<source src="http://7xl9b8.dl1.z0.glb.clouddn.com/b2d53773-614f-4e75-af76-3fd19eb26d10" type='video/mp4' />
</div>
<div id="myCaptions">
<div id="playerShow" class="srt">
<c:forEach items="${subtitleList}" var="subtitle">
<p class="p" id="${subtitle.id }"
onclick = "revise(this);"
beginTime="${subtitle.beginTime }"
endTime="${subtitle.endTime }"
beginTimeStr="${subtitle.beginTimeStr }"
oneSrtBody="${subtitle.oneSrtBody }"
otherSrtBody="${subtitle.otherSrtBody }">${subtitle.oneSrtBody }<br/>${subtitle.otherSrtBody }</p>
</c:forEach>
</div>
</div>
</section>
<footer>
<a class="proofBtn" onclick="proofRecord('${video.id }');">校对记录</a>
</footer>

<div class="takeNotes">
<div class="close iconfont icon-shanchu"></div>
<ul>
<div id="reviseRecord"></div>
</ul>
</div>

<div class="shak">
<div class="close1 iconfont icon-shanchu"></div>
<div class="revise">
<div class="reviseTop">
<p id="oneSrtBody"></p>
<p id="otherSrtBody"></p>
</div>
<div class="reviseMain ">
<div class="reviseMainLeft">
<form id="saveRevise">
<input type="hidden" name="userId" value="${opUser.id }"/>
<input type="hidden" name="subtitleId" id="subtitleId"/>
<input type="hidden" name="videoId" value="${video.id }"/>
<input type="hidden" id="beginTimeForSeek"/>
<textarea name="srtBody" id="reviseContent"></textarea>
</form>
</div>
<div class="reviseMainRight iconfont icon-qiepian13" onclick="saveRevise()"></div>
<div style="clear: both;"></div>
</div>
</div>
</div>

<script>
$(function(){
//点击 校对记录
$('.proofBtn').on('click',function(){
thePlayer.play(false);
$('.takeNotes').slideDown(500);
})
//点击关闭修改记录
$('.takeNotes .close').on('click',function(){
thePlayer.play(true);
$('.takeNotes').slideUp(500);
})

//点击关闭修改记录1
$('.shak .close1').on('click',function(){
$('.shak').slideUp(500);
var beginTime = $("#beginTimeForSeek").val();
thePlayer.seek(beginTime);
})
})

//暂停状态下执行
function stopanything(){
//播放状态执行
function biginanything(){
var MyMar=setInterval(Marquee,speed);
}
}
//暂停状态下执行
function stopanything(){

}
(function bottonm(){
if($(document).height()<$(window).height()){
$('.bottom_fix').css({'position':'fixed','bottom':'0px'});
$(document).height($(window).height()+'px');
}
})();
</script>
</body>
</html>

Html5视频播放器-VideoJS+Audio标签实现视频,音频及字幕同步播放的更多相关文章

  1. 基于Html5的兼容所有主流浏览器的在线视频播放器videoJs

    在一个新的项目上需要实现在线视频播放,原本打算借助优酷的视频存储和播放,但是发现这个需要用户注册优酷账户,严重影响用户体验,于是这个方案被毙掉了.于是开始了自己开发一个在线播放器的想法,当然尽量使用已 ...

  2. HTML5的Audio标签打造WEB音频播放器

    目前,WEB页面上没有标准的方式来播放音频文件,大多数的音频文件是使用插件来播放,而众多浏览器都使用了不同的插件.而HTML5的到来,给我们提供了一个标准的方式来播放WEB中的音频文件,用户不再为浏览 ...

  3. 打造自己的html5视频播放器

    前段时间重新学习了一下html5的video部分,以前只是停留在标签的使用上,这一次决定深入了解相关的API,并运用这些API打造一个简单的视频播放器.所谓“打造自己的”,就是要自己重写video标签 ...

  4. jqm视频播放器,html5视频播放器,html5音乐播放器,html5媒体播放器,video开展demo,html5视频播放演示示例,html5移动视频播放器

    最近看到很多有用的论坛html5视频播放的发展,音乐播放功能,大多数都在寻找答案.所以,我在这里做一个demo.对于大家互相学习.html5开发越来越流行,至于这也是一个不可缺少的一部分的视频. 如何 ...

  5. html5视频播放器 一 (改写默认样式)

    一个项目用到了html5视频播放器,于是就写了一个,走了很多坑,例如在chrome中加载视频出现加载异常等 先看看效果 是不是感觉换不错,以下是我播放器改写样式的布局. <!DOCTYPE ht ...

  6. html5视频播放器 二 (功能实现及播放优化)

    样式改写css,其中的一些按钮是在“阿里妈妈”上找的字体图标,就不向上传了. /* *CoolPlay视频播放器 * 2016年8月1日 * 627314658@qq.com * */ @font-f ...

  7. 一款开源免费跨浏览器的视频播放器--videojs使用介绍

    最近项目中的视频功能,需要做到浏览器全兼容,所以之前用html5实现的视频功能就需要进行改造了.在网上翻了个遍,试来试去,在所有的视频播放器中,就数它最实际了.首先我们来看看它的优点: 1.它是开源免 ...

  8. 【转】一款开源免费跨浏览器的视频播放器--videojs使用介绍

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  9. 免费视频播放器videojs中文教程

    Video.js是一款web视频播放器,支持html5和flash两种播放方式.更多关于video.js的介绍,可以访问官方网站介绍,我之前也写过一篇关于video.js的使用心得,有兴趣的可以点这里 ...

随机推荐

  1. Oracle DBA 必须掌握的 查询脚本:

    Oracle  DBA 必须掌握的 查询脚本: 0:启动与关闭 orcle 数据库的启动与关闭 1:连接数据库 2:数据库开启状态的实现步骤:       2-1:启动数据库           2- ...

  2. pads layout 自动打地孔

    对于PCBLayout来说,后期处理也是一项费时操作,比如为了让板子耦合的更好,会在板子空旷位置打上很多地过孔.“自动打地孔”则会让你省时又省心,一不小心就提前了工期哦,哈哈! 一.下面打开一个简单的 ...

  3. Ubuntu安装Sublime Text3插件Emmet的依赖PyV8

    通常情况下,插件是放在运行目录的Packages目录下,经过多番搜索资料,以及验证,ST3将插件放在来Installed Packages目录下,为此,如果遇到无法更新Emmet依赖库PyV8的时候, ...

  4. 【GIT】git 删除本地分支和远程分支、本地代码回滚和远程代码库回滚

    [git 删除本地分支] git branch -D br [git 删除远程分支] git push origin :br  (origin 后面有空格) git代码库回滚: 指的是将代码库某分支退 ...

  5. C# Common Log function

    public int Log(string info) { info = "-----------------------------" + DateTime.Now.ToStri ...

  6. 学习使人快乐8--Maven

    一.maven基操: MAVEN依赖之 坐标: 二.MAVEN依赖 type:依赖的类型,比如是jar包还是war包等 默认为jar,表示依赖的jar包 optional:标记依赖是否可选.默认值fa ...

  7. 对接携程供应商php加密解密类

    php加密解密类 <?php class Aes{ private $key = '6b4d63211b4ba869'; private $iv = 'dbbf079b95004f65'; pu ...

  8. 027 storm面试小题

    1.大纲 Storm工作原理是什么? 流的模式是什么?默认是什么? 对于mapreduce如何理解? Storm的特点和特性是什么? Storm组件有哪些? 2.Storm工作原理是什么? 相对于ha ...

  9. java位移运算符 转

    https://blog.csdn.net/qq_36134429/article/details/78286416#commentsedit java移位运算符不外乎就这三种:<<(左移 ...

  10. look back to 2018

    只写展望怎么行,还是缺一篇总结.2018年几乎没有怎么发朋友圈,需要一些文字记录一下这一年发生的事. 去年的现在,2018年的开端,结束了研一上学期充实的生活,下学期一项艰巨的任务就是完成大项目,一个 ...