Web上的MediaRecorder更换stream
今天有个老哥问我,MediaRecorder在录制过程中,能否改变在构造函数中引入的流。
这个我还真没有试过,之前写的H5直播虽然我一直声称在手机端可以选择前置或后置摄像头,但实际上一旦选择了就没法更改了......其实我确实有考虑过解决这个问题,但当时实在是太累(lan)了,最后答辩就给糊弄过去了,难得今天不想干正事,试试。
过程
首先直接MediaRecorder.stream=new_stream的想法可以省省,不用猜就知道这里面的stream肯定是个只读属性
一般遇到这种问题我都先去外网上看看有没有什么高见,堆栈溢出上看见这么一个:https://*.com/questions/57838283/is-it-possible-to-change-mediarecorders-stream?r=SearchResults
老哥上来就说做不到,emmmmmmmm....但是提问的人问的是track,我觉得可能跟我想的是不一样的,动手试试吧。既然没法修改stream,我直接new一个新的MediaRecorder替换原来的不可以吗?
记得之前看示例的时候有一个是教如何切换使用的设备的(Choose camera, microphone and speaker),里面演示了如何切换设备以及切换后的效果,怎么实现的并不重要,没那么多时间去细细品味,扒下来代码,找到自己以前写的MediaRecorder的代码,拿出作为代码人的骄傲,开始写一个缝合怪。写到饭点,看完API的顺道去看了一下自己的Chrome版本,放那里没管吃饭去了,回来一看Chrome界面不对,自己给我更新了……更新完之后发现最早写的MediaRecorder代码不管用了我日,好在还有另一份使用blob的还可以,得重新写自己的缝合怪了
写完之后大概是这样的:
在魔改原来sample代码的过程中,我在设备下拉菜单的事件触发函数里加上了代码,在设备改变之后,new一个新的MediaRecorder替代原来的,将新的设备的stream作为MediaRecorder的参数传入,将其绑定起来。
function gotStream(stream) {
//这个函数跟在getUserMedia之后,参数中的stream就是新设备的stream
window.stream = stream; // make stream available to console
videoElement.srcObject = stream;//在上面的video标签中显示
//缝合怪
//初始化MediaRecorder
var record_options = {
audioBitsPerSecond:128000,
videoBitsPerSecond:2500000,
mimeType : mimeType_for_test
}
//创建MediaRecorder
//注意MediaRecorder已经在js文件的开头声明
mediaRecorder=new MediaRecorder(stream,record_options);
//当录制的数据可用时
mediaRecorder.ondataavailable=function(e) {
//console.log(e.data);
if(e.data.size>0){
var reader = new FileReader();
var arr = [];
arr.push(e.data);
var blob = new Blob(arr,{'type':mimeType_for_test});
reader.readAsArrayBuffer(e.data);
reader.onloadend = function(e){
sourcebuffer.appendBuffer(reader.result);
sourcebuffer.addEventListener('updateend',function(){
});
}
}
}
//mediaRecorder.start(timecell);
mediaRecorder.onstart = function(e) {
console.log('Record onstart');
}
mediaRecorder.onstop = function(e) {
console.log('Record onstop');
}
//缝合怪的尾巴
return navigator.mediaDevices.enumerateDevices();//用于后面的函数更新设备标签
}
诶嘿嘿,不愧是我,轻易地就做到了一般人做不到的事情
但是在实际运行起来就遇到了很操蛋的问题
在录制过程中直接用new MediaRecorder替换原来的会导致下面的播放卡住,即便sourcebuffer一直在不停地append但是无法播放,于是我考虑是不是在改变stream之前将录制停止,new完之后再重新开始录制。当我这么做了之后遇到了下面的问题:
于是我分阶段在控制台中打印MediaRecorder,检查它的状态
对比上面三个可以发现,在刚刚切换完stream之后,MediaRecorder下的stream属性下的active属性值是false,当一段时间过后才会变为true,当其为false时试图调用MediaRecorder.start()就会导致报错。我看到了active下面还有个onactive,诶嘿嘿这个好东西啊,这不就是active变为true时的触发事件吗,赶紧绑定函数,变为true时就启动我的MediaRecorder!
过了好久好久
“onactive还没有被实现.......”,我靠了这帮人为什么这么喜欢挖坑不填啊。被逼无奈,在切换stream后等待,当stream.active的值为true时再start我的MediaRecorder。(这里又被自己蠢到了,代码苦手最近C++写太多了,我直接写了个while(1)里面写了个判断跳出循环,然后直接把页面给卡死了....蠢到自己不自知以为是页面开太多了头铁地又试了一次...)写个setTimeout完事
function tryRestartRecorder(){
if(mediaRecorder.stream.active){
try{
mediaRecorder.start(timecell);
}catch(e){}
}else{
setTimeout(tryRestartRecorder,100);
}
}
function changestream(){
try{
mediaRecorder.stop();//防止MediaRecorder还没有初始化
}catch(e){}
start();//切换stream的函数
setTimeout(tryRestartRecorder(),100);
}
这样就成了
收尾的时候发现不显示设备名称
这个博客里面提到需要部署到服务器上去才能够获取到设备名称,可能是因为不是https连接导致navigator.mediaDevices.enumerateDevices()函数没有权限
Demo
上一篇: 学校门口超级雷人的杜蕾斯广告
下一篇: vb.net中的配置文件总结
推荐阅读
-
Linux系统上Nginx+Python的web.py与Django框架环境
-
一种理论上最快的Web数据库分页方法
-
Linux上架设支持JSP+PHP的Web服务器
-
java web开发中获取tomcat上properties文件内容的方法
-
Linux系统上Nginx+Python的web.py与Django框架环境
-
Python Web程序部署到Ubuntu服务器上的方法
-
(二)Web框架-龙卷风Tornado之世界上最简单的Tornado示例
-
世界上最流行的Web服务器软件之一Apache服务
-
在电脑上如何设置让电脑壁纸自动更换 电脑壁纸自动更换的方法教程
-
Solr 16 - 增删改Solr中索引数据的几种方式 (在URL上或Web页面中操作)