【问题标题】:Youtube Player Api Get ScreenshotYoutube Player Api 获取截图
【发布时间】:2019-10-11 11:46:22
【问题描述】:

this page 上有一个iframe 我想从video 标签中获取屏幕截图,所以我必须到达iframe 标签中的视频标签。

当我打开控制台并运行这段代码时:

 const videoElement = document.getElementsByTagName('iframe')[0]
                 .contentWindow.document.getElementsByTagName('video')[0];

//Extracting picture from video tag
    const canvas = document.createElement('canvas');
        canvas.width = videoElement.videoWidth;
        canvas.height = videoElement.videoHeight;
        canvas.getContext('2d').drawImage(videoElement, 0, 0, canvas.width, canvas.height);

已抛出此错误:

Uncaught DOMException: Blocked a frame with origin "https://developers.google.com" from accessing a cross-origin frame.
    at <anonymous>:1:57

另外,我检查了this 问题

我的问题是如何从 YouTube Player API 获取屏幕截图?

【问题讨论】:

  • 您说您检查了链接到的问题,但它直接解决了您的问题 - 您不能直接与来自不同来源的 iframe 的内容进行交互。如果可以,那将破坏互联网的安全性。另外,为什么不直接使用官方 API,它可以让您获取缩略图/屏幕截图? - stackoverflow.com/a/2108248
  • 我需要从特定时间截屏假设视频长度为 100 秒,我可以在第 44 秒截屏。但缩略图是静态的
  • 这是有道理的,但这并不能改变您根本无法自己处理嵌入的事实(您的主要问题)。您的选择基本上是 - A) 下载视频并使用 FFMPEG 之类的东西来提取帧,B) 使用类似 puppeteer 的东西来运行无头 Chrome 并截取视频,或者 C) 使用像 @987654325 这样的 screenshot-api 服务@ 并将嵌入 URL 作为页面传递给屏幕截图。
  • 选项 A 看起来很完美,除了下载视频我认为 vlc 可以从网络流播放 youtube 视频,如果我可以从命令行使用 url 参数时间参数打开 vlc,它可以动态生成缩略图:videosolo.com/tutorials/download-video-with-vlc.html
  • @Joshua T 你能看看这个问题吗:askubuntu.com/questions/796575/… 我的意思是 vlc 可以打开 youtube 连接如果我可以用 vlc 将帧提取为图像,那就太好了。

标签: javascript iframe youtube-api youtube-javascript-api youtube-iframe-api


【解决方案1】:

据我所知,无法从 YouTube Player API 截屏,因为它基于 iFrame。如果你想在你自己的应用程序(不仅仅是浏览器扩展)中制作它们,这个操作将被 CORS 禁止(你得到异常的原因)。

唯一的解决方法是使用可以从 YouTube 获得的数据将 YouTube 视频作为源放入视频 HTML 元素中。 这段代码应该很方便获取视频的源网址:

class YoutubeVideo {

    constructor(video_id, callback) {
        return (async () => {
            // You should also redirect those requests
            // through your own API that would permit CORS
            const response = await fetch(`https://www.youtube.com/get_video_info?video_id=${video_id}`, {
                headers: { 'Content-Type' : 'text/plain'}
            });
            const video_info = await response.text();
            
            let video = this.decodeQueryString(video_info);
            if (video.status === 'fail') {
                return callback(video);
            }
            
            if (video.url_encoded_fmt_stream_map) 
                video.source = this.decodeStreamMap(video.url_encoded_fmt_stream_map);

            return callback(video);
        })();
    }

    decodeQueryString(queryString) {
        var key, keyValPair, keyValPairs, r, val, _i, _len;
        r = {};
        keyValPairs = queryString.split("&");
        for (_i = 0, _len = keyValPairs.length; _i < _len; _i++) {
            keyValPair = keyValPairs[_i];
            key = decodeURIComponent(keyValPair.split("=")[0]);
            val = decodeURIComponent(keyValPair.split("=")[1] || "");
            r[key] = val;
        }
        return r;
    }

    decodeStreamMap(url_encoded_fmt_stream_map) {
        var quality, sources, stream, type, urlEncodedStream, _i, _len, _ref;
        sources = {};
        _ref = url_encoded_fmt_stream_map.split(",");
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
            urlEncodedStream = _ref[_i];
            stream = this.decodeQueryString(urlEncodedStream);
            type = stream.type.split(";")[0];
            quality = stream.quality.split(",")[0];
            stream.original_url = stream.url;
            stream.url = "" + stream.url + "&signature=" + stream.sig;
            sources["" + type + " " + quality] = stream;
        }
        return sources;
    }
}

在构造函数中传递给回调的对象将具有 source 属性,其中包含所有可用视频类型和质量的源链接,您可以在浏览器的控制台上更好地检查它们。 然而,并不是所有的 YouTube 视频都可以这样处理,当你只能得到禁止错误或空源时,我遇到了更多限制的文件。

帮助我找到此解决方案的资源: https://github.com/endlesshack/youtube-video

基于此解决方案工作的资源: http://youtubescreenshot.com/

基于 expressjs 服务器的简单 Web App 概念证明: https://github.com/RinSer/YouCut

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 2014-12-23
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2021-07-24
    相关资源
    最近更新 更多