最近帮别人搜索html5 player相关的问题,在网上查看了一些资料。整理一下网上搜到的一些关于
Javascript实现H.264视频流播放,视频截图功能的链接。因为我不是从事前端开发相关的工作,
对前端相关的知识了解有限,所以无法提供现成的解决方案,或者准确定位最合适的1-2个链接。
只能把看上去还可以的链接保存下来,以作记录:
(1) 视频直播
1. use html5 video tag with MSE for h264 live streaming
2. JavaScript H.264 decoder -- Broadway
3. videojs做直播、弹幕
4. HTML5视频方案:支持iPad Safari、Firefox、Chrome、IE9876
5. HTML5 audio/video标签 整理
6. Video.js Record -- A video.js plugin for recording audio/video/image files.
7. js+html手机端视频截屏
(2)视频截图
8. canvas与html5实现视频截图功能
9. video用canvas实现截图和上传
10. 用原生JS和html5进行视频截图并保存到本地
其实有些链接内容是类似的,比如 通过canvas实现 视频截图。 但我还是把链接记录下来了。
(3)直播录像
从逻辑上分析,当用户选择“录像“操作时,可以通过获取h.264直播流,处理数据的时候,将data buffer
复制一份,并保存。待用户选择“结束录像”操作时,进行编码(如MP4格式)以及保存为录像文件的动作。
网上搜索到解决办法,主要分为两种: WebRTC 和 MediaRecorder。 但存在的问题是,一些浏览器(如Safari),
或者旧的浏览器(chrome, firefox)可能不支持。
11. stackoverflow: HTML 5 video recording and storing a stream
12. HTML5’s Media Recorder API in Action on Chrome and Firefox
通过网页和回复,发现了2个关于示例代码的Github链接:
Chrome and Firefox : Media-Recorder-API-Demo
Edge and Safari : audio-recorder-polyfill
13. AngularJS + HTML5 record audio file
14.html5 pc端录制视频+MediaStreamRecorder
这个链接上附上了代码。为了防止链接失效,我将代码也一并转过来了。答主借鉴了一下链接:
SegmentFault : https://segmentfault.com/q/1010000011489899
git官方 : https://github.com/streamproc/MediaStreamRecorder
建议大家去 链接的原始地址 查看 。
<video width="100%" height="480" id="myVideo"></video>
</div>
<button onclick="videolz()" type="button" class="btn btn-danger" style="width: 100%; font-size: 32px"><span class="glyphicon glyphicon-facetime-video" aria-hidden="true" id="videostr">视频描述</span></button>
// 判断浏览器
var root ="<%=basePath %>";
var aa = '' ; //防止两次上传
var mediaRecorder ;
var index=1;//定时加1
var dingshi;
var mediaConstraints = { audio: true, video: { width: 1280, height: 720 } };
function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
}
function onMediaError(e) {
}
function onMediaSuccess(stream) {
var video = document.querySelector('video');
// 赋值 video 并开始播放
video.srcObject = stream;
video.onloadedmetadata = function(e) {
video.play();
};
mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.stream = stream;
/* // 录像api的调用 */
mediaRecorder.mimeType = 'video/mp4';
dingshi = window.setInterval(function(){
$("#videostr").html("保存视频"+index+"秒");
index++;
}
,1000);
mediaRecorder.start(12000000000);
// 停止录像以后的回调函数
mediaRecorder.ondataavailable = function (blob) {
if(aa == ""){
var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.mp4', {
type: 'video/mp4'
});
var formData = new FormData();
formData.append('file', file);
console.log(formData);
$.ajax({
url : root+"/upload/video.do",
type : "post",
cache : false,
data: formData,
dataType : "json",
processData: false,
contentType: false,
error : function() {
alert("暂时无法操作,请刷新后再试!");
},
success : function(result) {
if (result.code == 0) {
var params = result.data;
console.log(params);
console.log(params.fileUrl);
/* $("#lzvideo").attr("src", params.fileUrl); */
} else {
}
}
});
aa = blob;
}
};
}
function videolz(){
if( $("#videostr").text()=="视频描述"){
$("#videostr").html("保存视频");
$("#videostr").removeClass("glyphicon-facetime-video");
$("#videostr").addClass("glyphicon-pause")
/* $("#videos").append("<video width=\"100%\" height=\"320px\" id=\"myVideo\"></video>") */
// 开始录像
$("#myVideo").show();
captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
}else{
$("#videostr").html("视频描述");
$("#videostr").addClass("glyphicon-facetime-video");
$("#videostr").removeClass("glyphicon-pause")
/* $("#myVideo").remove(); */
// 停止录像
/* mediaRecorder.stop(); */
mediaRecorder.stream.stop();
/* $("#myVideo").unbind(); */
index=1;
window.clearInterval(dingshi);
}
}
</script>
/*
* 上传视频
*/
@RequestMapping(value="video")
@ResponseBody
public Result uoloadVideo(@RequestParam("file") MultipartFile file,Model model,HttpServletRequest request, HttpServletResponse response) {
Result result = new Result();
Map<String, Object> data = new HashMap<String, Object>();
String serverPath = "/upload/" + new SimpleDateFormat("yyyyMM").format(new Date()) + "/";
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
String filePath = request.getSession().getServletContext().getRealPath(serverPath);
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
String fileUrl = request.getContextPath() + serverPath + fileName;
File targetFile = new File(filePath, fileName);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
try {
file.transferTo(targetFile);
System.out.println(basePath);
data.put("fileUrl", basePath+fileUrl);
result = new Result(0, "上传成功", data);
} catch (Exception e) {
result = new Result(1, "上传异常");
}
return result;
}