+
32
-

回答

思路:window.open打开标签页窗口,然后调用标签页录制,手动选择录制的新标签,然后发送message到子标签通知播放动画与声音,点击结束下载webm视频,通过ffmpeg转换成mp4格式。

800_auto

完整示例代码

点击查看全文

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>录制权限控制动画播放</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            background: #f0f0f0;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }
        #status {
            margin-top: 20px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <h2>录制权限控制动画播放</h2>
    <button onclick="startRecording()">开始录制</button>
    <div id="status">等待操作...</div>

    <script>
        let popupWindow = null;
        let mediaRecorder = null;

        // 弹出窗口的 HTML 内容(含 SVG 动画和语音播放逻辑)
        const popupHTML = `
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>弹出窗口</title>
                <style>
                    body {
                        margin: 0;
                        background: #1a1a2e;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        height: 100vh;
                    }
                    .circle {
                        width: 100px;
                        height: 100px;
                        border-radius: 50%;
                        background: linear-gradient(45deg, #ff6ec4, #7873f5);
                        animation: spin 2s linear infinite;
                        opacity: 0;
                        transform: scale(0.5);
                    }
                    .animate {
                        animation: spin 2s linear infinite;
                        opacity: 1;
                        transform: scale(1);
                    }
                    @keyframes spin {
                        0% { transform: rotate(0deg) scale(1); }
                        100% { transform: rotate(360deg) scale(3); }
                    }
                </style>
            </head>
            <body>
            <audio  id="bgMusic" style="display:none;" controls="controls" src="//repo.bfw.wiki/bfwrepo/sound/5c89fd22dea6948307.mp3" ></audio>
                <div class="circle" id="circle"></div>
                  <button id="playBtn">先点我</button>
                <script>
  document.getElementById('playBtn').addEventListener('click', function() {
    this.style.display = "none";
});
                    // 监听主页面发送的消息
                    window.addEventListener('message', (event) => {
                        if (event.data === 'play') {
                            // 启动动画
                            document.getElementById('circle').classList.add('animate');
                     
                               // 播放背景音乐
            const audio = document.getElementById('bgMusic');
            audio.play().catch(err => {
                console.error('播放失败:', err);
                alert('请先与页面交互(如点击按钮)以启用自动播放');
            });

                            // 播放语音
                            //const utterance = new SpeechSynthesisUtterance('这是一个 SVG 动画演示');
                            //utterance.lang = 'zh-CN';
                           // utterance.rate = 1;
                            //utterance.pitch = 1;
                            //utterance.volume = 1;
                            //window.speechSynthesis.speak(utterance);
                        }
                    });
                    
                     
                <\/script>
            </body>
            </html>
        `;

        async function startRecording() {
            // 1️⃣ 打开手机尺寸的新标签页
            const width = 1080;
            const height = 1920;
            const left = window.screen.width / 2 - width / 2;
            const top = window.screen.height / 2 - height / 2;

            popupWindow = window.open('about:blank', '_blank', 
                `width=${width},height=${height},left=${left},top=${top}`);

            popupWindow.document.open();
            popupWindow.document.write(popupHTML);
            popupWindow.document.close();
            

            document.getElementById('status').textContent = '新窗口已打开并写入内容...';

            try {
                // 2️⃣ 请求屏幕录制权限
                document.getElementById('status').textContent = '请求屏幕录制权限...';
                const displayStream = await navigator.mediaDevices.getDisplayMedia({ video: { cursor: "motion", displaySurface: "browser" }, // "browser" hints for tab
            audio: true });
                
              const tracksToRecord = [...displayStream.getTracks()]; // 包含视频+音频

               combinedStreamForRecorder = new MediaStream(tracksToRecord);

                // 3️⃣ 初始化 MediaRecorder
                mediaRecorder = new MediaRecorder(combinedStreamForRecorder, {
                     mimeType: 'video/webm; codecs=vp9,opus' // 支持音频编码
                });

                const chunks = [];
                mediaRecorder.ondataavailable = (event) => {
                    if (event.data.size > 0) chunks.push(event.data);
                };

                mediaRecorder.onstop = () => {
                    // 下载视频
                    const blob = new Blob(chunks, { type: 'video/webm' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = 'recording.webm';
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                    document.getElementById('status').textContent = '录制完成并已下载!';

                    // 关闭弹出窗口
                    if (popupWindow) popupWindow.close();
                };

                // 4️⃣ 开始录制并通知弹出窗口播放动画
                mediaRecorder.onstart = () => {
                    document.getElementById('status').textContent = '录制已开始,通知弹出窗口播放动画...';
                    popupWindow.postMessage('play', '*'); // 发送播放信号
                };

                // 5️⃣ 启动录制
                mediaRecorder.start(100); // 每 100ms 收集一次数据块

                // 6️⃣ 停止录制(示例:10 秒后)
                setTimeout(() => {
                    mediaRecorder.stop();
                    displayStream.getTracks().forEach(track => track.stop());
                }, 10000);

            } catch (err) {
                console.error('录制失败:', err);
                document.getElementById('status').textContent = `录制失败: ${err.message}`;
                if (popupWindow) popupWindow.close();
            }
        }
    </script>
</body>
</html>

2、

网友回复

我知道答案,我要回答