0

我有一个网页,我在 iframe 中嵌入了 YouTube 视频。我需要捕获 YouTube 视频的屏幕截图。由于跨域限制,使用 html2canvas 和 dom2image 之类的库不起作用。

因此,我想到了使用getDisplayMedia()捕获完整浏览器窗口的屏幕截图,然后使用drawImage()裁剪相关部分的想法。在我看来,这似乎完全有道理,只需识别 iframe 的位置,然后使用 drawImage 裁剪它。但是,它不会裁剪所有屏幕尺寸的相关部分。当我更改屏幕分辨率或放大时,它似乎坏了。

另一个想法是编写一个人工智能算法来捕捉这一点。但我认为这是矫枉过正。关于如何使其适用于所有屏幕尺寸和分辨率的任何想法?

<h1>Hello</h1>
<div style="margin: 10;">
    <iframe 
        id="youtubeiframe" 
        width="640" 
        height="340" 
        src="https://www.youtube.com/embed/vDYP6AKw8bk?controls=0" 
        title="YouTube video player" frameborder="0" 
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
        allowfullscreen>
    </iframe>
</div>
<div id="picture" style="margin-top:60; background-color:'gray'"></div> 

<script>
        navigator.mediaDevices.getDisplayMedia({ preferCurrentTab: true }).then(stream => {
        captureStream = stream;
        track = captureStream.getVideoTracks()[0];
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        const offsets = document.getElementById("youtubeiframe")?.getBoundingClientRect();
        const posX = offsets.left;
        const posY = offsets.top;
        const width = offsets.width;
        const height = offsets.height;
        canvas.width = width;
        canvas.height = height;

        let image = new ImageCapture(track);
        const bitmap = image.grabFrame().then(bitmap => {
            context?.drawImage(bitmap, posX, posY, width, height, 0, 0, width, height);
            const pic = document.getElementById("picture");
            if(pic.childElementCount > 0)
                pic.replaceChild(canvas,pic.children[0]);
            else
                pic.appendChild(canvas);
        });
        
    });
    
</script>
4

1 回答 1

0

我介绍了一个中间步骤,将图像缩放到与浏览器窗口相同的大小,然后按预期进行裁剪。这是它的代码 -

const tempCanvas = document.createElement("canvas");
tempCanvas.width = window.innerWidth;
tempCanvas.height = window.innerHeight;
const tempContext = tempCanvas.getContext("2d");
tempContext?.drawImage(bitmap,0,0,tempCanvas.width,tempCanvas.height);
context?.drawImage(tempCanvas, posX, posY, width, height, 0, 0, width, height);

这是包含上述修复的完整代码 -

<h1>Hello</h1>
<div style="margin: 10;">
    <iframe 
        id="youtubeiframe" 
        width="640" 
        height="340" 
        src="https://www.youtube.com/embed/vDYP6AKw8bk?controls=0" 
        title="YouTube video player" frameborder="0" 
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
        allowfullscreen>
    </iframe>
</div>
<div id="picture" style="margin-top:60; background-color:'gray'"></div> 

<script>
        navigator.mediaDevices.getDisplayMedia({ preferCurrentTab: true }).then(stream => {
        captureStream = stream;
        track = captureStream.getVideoTracks()[0];
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        const offsets = document.getElementById("youtubeiframe")?.getBoundingClientRect();
        const posX = offsets.left;
        const posY = offsets.top;
        const width = offsets.width;
        const height = offsets.height;
        canvas.width = width;
        canvas.height = height;

        let image = new ImageCapture(track);
        const bitmap = image.grabFrame().then(bitmap => {
            const tempCanvas = document.createElement("canvas");
            tempCanvas.width = window.innerWidth;
            tempCanvas.height = window.innerHeight;
            const tempContext = tempCanvas.getContext("2d");
            tempContext?.drawImage(bitmap,0,0,tempCanvas.width,tempCanvas.height);
            context?.drawImage(tempCanvas, posX, posY, width, height, 0, 0, width, height);
            const pic = document.getElementById("picture");
            if(pic.childElementCount > 0)
                pic.replaceChild(canvas,pic.children[0]);
            else
                pic.appendChild(canvas);
        });
        
    });
    
</script>
于 2022-02-14T10:07:02.497 回答