测试了2.4.x 3.x暂时无法完美实现,因为 AudioContext在3.0闭包内,外面无法获取
const { ccclass, property } = cc._decorator;
@ccclass
export default class Screencap extends cc.Component {
onLoad(): void {
//获取视频通道
var videoStream = cc.game.canvas.captureStream();
//获取cocos音频解析AudioContext
var context = cc.sys["__audioSupport"].context
//创建音频通道
var audioSteramNode = context.createMediaStreamDestination();
//修改 AudioContext createBufferSource 原型链 把创建的 AudioBufferSourceNode 连接 音频通道
const createBufferSource = AudioContext.prototype.createBufferSource;
AudioContext.prototype["_createBufferSource"] = createBufferSource;
AudioContext.prototype["createBufferSource"] = function () {
var _currentSource = this["_createBufferSource"]();
_currentSource.connect(audioSteramNode);
return _currentSource;
}
// 创建一个0赫兹的音效,防止 没有声音录制失败 0.1秒后停止声音
var oscillator = context.createOscillator();
oscillator.type = "square";
oscillator.frequency.value = 0;
oscillator.connect(context.destination);
oscillator.connect(audioSteramNode);
oscillator.start();
oscillator.stop(context.currentTime + 0.1);
//添加音频track到视频通道
videoStream.addTrack(audioSteramNode.stream.getAudioTracks()[0]);
//获取支持录制的格式
var getSupportedMimeTypes = function () {
const VIDEO_TYPES = [
"webm",
"mp4",
"ogg",
"x-matroska",
];
const VIDEO_CODECS = [
"vp9",
"vp9.0",
"vp8",
"vp8.0",
"h265",
"h.265",
"h264",
"h.264",
"avc1",
"av1",
"opus",
];
const supportedTypes = [];
VIDEO_TYPES.forEach((videoType) => {
const type = `video/${videoType}`;
VIDEO_CODECS.forEach((codec) => {
const variations = [
`${type};codecs=${codec}`,
`${type};codecs:${codec}`,
`${type};codecs=${codec.toUpperCase()}`,
`${type};codecs:${codec.toUpperCase()}`,
`${type}`
]
variations.forEach(variation => {
if (MediaRecorder.isTypeSupported(variation))
supportedTypes.push(variation);
})
});
});
return supportedTypes;
}
const supportedMimeTypes = getSupportedMimeTypes();
//创建录制程序
var mediaRecorder = new MediaRecorder(videoStream, { mimeType: supportedMimeTypes[0] });
var chunks = [];
mediaRecorder.addEventListener('dataavailable', (e) => {
chunks.push(e.data)
})
// 监听停止保存视频
mediaRecorder.addEventListener('stop', function () {
var blob = new Blob(chunks, { type: chunks[0].type });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'video.webm';
a.click();
})
//监听浏览器后台,暂停游戏
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === "hidden") {
console.log('当前页签隐藏,即打开新页签')
cc.game.pause();
mediaRecorder.pause();
}
if (document.visibilityState === "visible") {
console.log('当前页签显示,即打开当前页签')
cc.game.resume();
// 网页重新获得焦点
mediaRecorder.resume();
}
});
//js监听键盘ctrl+s快捷键保存
document.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.key == "s") {
mediaRecorder.stop();
event.preventDefault();
}
}, true);
mediaRecorder.start();
}
}