前言
在上一篇文章中初步介绍了如何利用webrtc简化和增强webrtc直连过程中遇到的繁琐和瓶颈问题,以及简单的实现网络视频通话的小教程,本篇文章将介绍如何在上述视频通话过程中实时录制通话数据.
准备基础的通话demo,开始录制教程
本次的demo以上次使用的demo为主,增加录制功能
初始化录制和回放janus插件
插件名称
janus.plugin.recordplay
that.$store.state.recordPlay
为初始化插件后获取的全局handle,所有关于录制的句柄都要用这个.
// 初始化视频录制回放handle
initRecordPlay(){
const that = this;
janus.attach({
plugin: "janus.plugin.recordplay",
success: function(pluginHandle) {
that.$store.commit("setRecordPlay",pluginHandle)
Janus.log("Plugin attached! (" + pluginHandle.getPlugin() + ", id=" + pluginHandle.getId() + ")");
},
error: function(cause) {
Janus.error(" -- Error attaching recordplay plugin...", error);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message :::", msg);
var result = msg["result"];
if(result) {
if(result["status"]){
var event = result["status"];
if(event === 'preparing' || event === 'refreshing') {
Janus.log("Preparing the recording playout");
that.$store.state.recordPlay.createAnswer(
{
jsep: jsep,
media: {
video:false,
audio:false,
data:true
},
success: function(jsep) {
var body = { request: "start" };
that.$store.state.recordPlay.send({ message: body, jsep: jsep });
},
error: function(error) {
Janus.error("WebRTC error:", error);
}
});
if(result["warning"]){
console.log()
}
} else if(event === 'recording') {
if(jsep)
that.$store.state.recordPlay.handleRemoteJsep({ jsep: jsep });
var id = result["id"];
if(id) {
Janus.log("The ID of the current recording is " + id);
}
} else if(event === 'playing') {
Janus.log("Playout has started!");
} else if(event === 'stopped') {
Janus.log("Session has stopped!");
}
}
}
},
onlocalstream:function(stream){
console.log("本地视频")
},
onremotestream: function(stream) {
console.log("远程视频")
that.setTargetMedia(stream,'recordPlay')// 监听到视频源将其输出到指定的video标签
Janus.debug(" ::: Got a remote stream :::", stream);
},
});
},
开始录制
利用上面初始化号的全局录制句柄
that.$store.state.recordPlay
向janus发送具体的指令,开始录制.
recordvideo(){
const that = this;
if(!this.username){
this.$message.error("用户名不能为空")
return
}
that.$store.state.recordPlay.createOffer({
success: function(jsep) {
console.log("Got SDP!", jsep);
var body = { request: "record", name: getNowStrTime(new Date())+"-"+that.username };
that.$store.state.recordPlay.send({ message: body, jsep: jsep });
},
error: function(error) {
that.$store.state.recordPlay.hangup();
}
});
},
结束录制
本质上就是挂断录制的那个句柄
stoprecordvideo(){
this.$store.state.recordPlay.hangup();
},
获取录制的视频
这个
list
指令会返回录制的视频集合,后续可以根据具体每个视频的ID去播放视频
loadAllvideos(){
const that = this;
var body = { request: "list" };
this.$store.state.recordPlay.send({ message: body,success:function(res){
console.log("videos:",res)
}})
},
以上就是获取到刚才录制的基础信息,字段name是录制的时候发送的参数
var body = { request: "record", name: getNowStrTime(new Date())+"-"+that.username };
这边定义的,时间和登录用户
播放录制的内容
根据上面获取到的录制信息集合中的id字段,通过录制句柄发送播放指令即可
playvideo(row){
// row.id 即为上述获取到的集合中每个具体项的ID
var body = { request: "play",id:row.id };
this.$store.state.recordPlay.send({ message: body})
},
这里发送
play
指令后,句柄会根据这个做出响应,具体可以看到初始化插件中onmessage
监听中的信息,当然下面的在初始化插件的时候已经写好了.
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message :::", msg);
var result = msg["result"];
if(result) {
if(result["status"]){
var event = result["status"];
if(event === 'preparing' || event === 'refreshing') {
Janus.log("Preparing the recording playout");
that.$store.state.recordPlay.createAnswer(
{
jsep: jsep,
media: {
video:false,
audio:false,
data:true
},
success: function(jsep) {
Janus.debug("Got SDP!", jsep);
var body = { request: "start" };
that.$store.state.recordPlay.send({ message: body, jsep: jsep });
},
error: function(error) {
Janus.error("WebRTC error:", error);
}
});
if(result["warning"]){
console.log()
}
} else if(event === 'recording') {
// Got an ANSWER to our recording OFFER
if(jsep)
that.$store.state.recordPlay.handleRemoteJsep({ jsep: jsep });
var id = result["id"];
if(id) {
Janus.log("The ID of the current recording is " + id);
}
} else if(event === 'playing') {
Janus.log("Playout has started!");
} else if(event === 'stopped') {
Janus.log("Session has stopped!");
}
}
}
},
结束播放
stopplayvideo(row){
//这里的id和上面播放的ID一样,
var body = { request: "stop",id:row.id };
this.$store.state.recordPlay.send({ message: body})
},
如何下载录制的视频
janus本身的录制信息
janus录制的视频格式并不直接是mp4格式,而是针对每个视频有三个文件
.nfo
内容是上面获取录制信息的时候获取到的每个视频文件的基本信息,比如视频名称和视频文件,音频文件
[2464070935677548]
name = 2021-08-15-19-22-19-aaa
date = 2021-08-15 11:22:20
audio = rec-2464070935677548-audio.mjr
video = rec-2464070935677548-video.mjr
如何转换到mp4
janus虽然直接保存的上面的非mp4格式,但是也同样提供了转换成mp4格式的
插件
,下面我将如何使用插件的方法写在下面的脚本里.
本质就是将对应的.mjr
文件转换成基本的视频(.webm
)和音频文件(.opus
),然后再利用ffmpeg
合并视频和音频源,输出mp4
,大体脚本如下,如果想要完整脚本的话可以留言联系我.
tmp_video=./tmp/mjr-$RANDOM.webm
tmp_audio=./tmp/mjr-$RANDOM.opus
januspprec_dir=/usr/local/bin/
$januspprec_dir/janus-pp-rec ./rec-2464070935677548-audio.mjr $tmp_video
$januspprec_dir/janus-pp-rec ./rec-2464070935677548-video.mjr $tmp_audio
-----------------------
ffmpeg -i $tmp_audio -i $tmp_video -c:v copy -c:a opus -strict experimental 2464070935677548-aaa.mp4