如何在嵌入的YouTube播放列表中禁用“相关视频”

17

我需要在iframe中嵌入YouTube播放列表。我不希望用户能够退出这个播放列表,因此我需要禁用“相关视频”和“更多视频”功能(当视频停止时显示更多视频的功能和在视频完成时显示它们的功能)。

我尝试了一些解决方法,但它们只适用于单个视频(而非播放列表),并且大部分在?rel=0行为改变后停止工作。有没有办法做到这一点?

这是我的代码:

.rep {
   position: absolute;
   top: 0px;
   left: 0px;
   width: 1280px;
   height: 640px;
   z-index: 6;
}
<iframe class="rep" src="https://www.youtube.com/embed/videoseries?list=PLUl4u3cNGP63gFHB6xb-kVBiQHYe_4hSi" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

编辑:视频必须按顺序显示,因此我无法使用rel仅显示播放列表中的视频。而且,如果您单击它们,将会出现一个嵌入框外的YouTube页面。


从2018年9月25日开始,rel参数的行为将发生变化。这个变化的影响是您将无法禁用相关视频。但是,您可以选择指定在播放器中显示的相关视频应来自刚刚播放的视频所在的频道。https://developers.google.com/youtube/player_parameters#showinfo - Charlene Vas
是的,那正是我在你刚刚删除的那个答案中回答你的内容。我正在寻找一个解决方法。 - Luis Fernandez
我有点困惑,我刚刚尝试了<iframe class="rep" src="https://www.youtube.com/embed/videoseries?list=PLUl4u3cNGP63gFHB6xb-kVBiQHYe_4hSi&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>,它不仅在暂停时阻止了“更多视频”的出现,而且还在结尾处删除了相关视频。这就是你想要的,对吧? - Gosi
这对我不起作用。你添加了CSS吗?如果没有,播放器将太小而无法显示相关视频。关于最后的视频,它们只会在播放列表的最后一个视频之后显示。 - Luis Fernandez
是的,你说得对,一旦我添加了CSS,问题就出现了。 - Gosi
11个回答

18
如果我查看YouTube嵌入播放器和播放器参数文档,如果暂停视频,就没有这样的东西可以对更多视频部分进行排序。为了尽可能接近您的目标,我建议使用以下两个参数:

您可以添加:
  • listType=playlist
  • rel=0 :关闭来自更多视频部分的相关视频。

    注意: rel=0的行为将在2019年9月25日后被删除。


结论:

这似乎是不可能实现的。使用默认的YouTube嵌入iframe。
您可能需要考虑查找其他具有播放列表选项的播放器。 例如JW Player,请注意您需要此播放器的许可证,JW Player播放列表文档 我也阅读了一些关于JW Player的内容,他们目前不支持YouTube视频。但也许有其他具有免费功能的播放器。


我今天尝试了一下,rel=0仍然有效。 - Rashid

7

如果你在播放列表链接的结尾处添加 &rel=0 - 相关视频中将只显示来自你的播放列表的视频。例如:

<iframe class="rep" src="https://www.youtube.com/embed/videoseries?list=PLUl4u3cNGP63gFHB6xb-kVBiQHYe_4hSi&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

如果从链接中删除&rel=0,它会展示来自Youtube的随机视频。

1
我需要让用户无法跳过视频,这意味着我不能使用新的rel。此外,这样做会打开一个YouTube页面(如果您点击相关视频),我不希望发生这种情况。 - Luis Fernandez

6

2021年更新

Youtube现在似乎有一个循环功能,可以用来去除“相关视频”。它的基本作用是当你的视频结束时,重新开始播放而不是显示(不)相关视频。在我这种情况下,它完美地起到了作用。以下是代码:

https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1

请确保在代码中将两个VIDEO_ID替换为您的视频ID。无需创建播放列表。 允许启用播放器控件的完整iframe代码示例。
<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1" title="YouTube video player" rel="0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

完整的iframe代码示例,已禁用播放器控件。
<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1&controls=0" title="YouTube video player" rel="0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

无法正常工作,最后仍然建议视频(带/不带播放器控件)... - 15Step
如果你也加上 listType=playlist,它就能工作。 - Simon

3
这里有一个解决方法,虽然不是最好的,但它可以阻止烦人的推荐。它会循环播放播放列表,从而不给 YouTube 机会停下来并向您展示推荐,以使用户返回 YouTube。这对我很有效。如果您看到它按顺序播放我的列表,然后播放下一个,所有这些都没有弹出任何推荐。如果您停止它,它就会停在那里。希望它有所帮助,关键是0&loop https://codesandbox.io/s/adoring-tereshkova-nwv8i
<!DOCTYPE html>
<html>

<head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
</head>

<body>
    <div id="app"></div>
<iframe width="100%" height="425" src="https://www.youtube.com/embed/HdEN2JinZVE?autoplay=&showinfo=0&loop=1&list=PLvNxGp1V1dOwpDBl7L3AJIlkKYdNDKUEs&rel=0" frameborder="0" allowfullscreen></iframe>
    <script src="src/index.js">
    </script>
</body>

</html>

2

在我的情况下,这是有效的,您可以尝试这样做:

https://www.youtube-nocookie.com/embed/{videoId}?rel=0&amp;showinfo=0

2

我刚刚发现了一个很棒的网站,它为你的问题提供了一个解决方案。代码有点长,但我认为它可以解决问题。如果你向上滚动一点,他们有一个示例。https://www.maxlaumeister.com/blog/hide-related-videos-in-youtube-embeds/#hideyt-embed-code

<!-- https://maxl.us/hideyt -->
<style>
    .hytPlayerWrap {
        display: inline-block;
        position: relative;
    }

    .hytPlayerWrap.ended::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        cursor: pointer;
        background-color: black;
        background-repeat: no-repeat;
        background-position: center;
        background-size: 64px 64px;
        background-image: url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==);
    }

    .hytPlayerWrap.paused::after {
        content: "";
        position: absolute;
        top: 70px;
        left: 0;
        bottom: 50px;
        right: 0;
        cursor: pointer;
        background-color: black;
        background-repeat: no-repeat;
        background-position: center;
        background-size: 40px 40px;
        background-image: url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSIxNzA2LjY2NyIgaGVpZ2h0PSIxNzA2LjY2NyIgdmlld0JveD0iMCAwIDEyODAgMTI4MCI+PHBhdGggZD0iTTE1Ny42MzUgMi45ODRMMTI2MC45NzkgNjQwIDE1Ny42MzUgMTI3Ny4wMTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+);
    }
</style>
<div class="hytPlayerWrapOuter">
    <div class="hytPlayerWrap">
        <iframe width="640" height="360" src="https://www.youtube.com/embed/`**YOUR VIDEO ID HERE**`?rel=0&enablejsapi=1" frameborder="0"></iframe>
    </div>
</div>
<script>
    "use strict";
    document.addEventListener('DOMContentLoaded', function () {
        if (window.hideYTActivated) return;
        let onYouTubeIframeAPIReadyCallbacks = [];
        for (let playerWrap of document.querySelectorAll(".hytPlayerWrap")) {
            let playerFrame = playerWrap.querySelector("iframe");
            let tag = document.createElement('script');
            tag.src = "https://www.youtube.com/iframe_api";
            let firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
            let onPlayerStateChange = function (event) {
                if (event.data == YT.PlayerState.ENDED) {
                    playerWrap.classList.add("ended");
                } else if (event.data == YT.PlayerState.PAUSED) {
                    playerWrap.classList.add("paused");
                } else if (event.data == YT.PlayerState.PLAYING) {
                    playerWrap.classList.remove("ended");
                    playerWrap.classList.remove("paused");
                }
            };
            let player;
            onYouTubeIframeAPIReadyCallbacks.push(function () {
                player = new YT.Player(playerFrame, {events: {'onStateChange': onPlayerStateChange}});
            });
            playerWrap.addEventListener("click", function () {
                let playerState = player.getPlayerState();
                if (playerState == YT.PlayerState.ENDED) {
                    player.seekTo(0);
                } else if (playerState == YT.PlayerState.PAUSED) {
                    player.playVideo();
                }
            });
        }
        window.onYouTubeIframeAPIReady = function () {
            for (let callback of onYouTubeIframeAPIReadyCallbacks) {
                callback();
            }
        };
        window.hideYTActivated = true;
    });
</script>

不幸的是,这对播放列表不起作用,并且它在我想要显示它的浏览器上也不起作用。 - Luis Fernandez
请在此处放置代码,而不是链接,因为链接可能随时关闭或失效。 - Rin Minase

2

0

我发现,如果YouTube频道的视频少于(我不知道具体数量,但绝对少于20个,多于40个),并且iframe YouTube URL具有rel=0属性,则相关视频部分将完全不显示。


这并没有回答问题。一旦您拥有足够的 声望,您就可以在任何帖子下发表评论; 相反,提供不需要询问者澄清的答案。- [来自审查] (/review/late-answers/32783032) - Augustas

0

很遗憾,无法将外部CSS或JS应用于网页中的iframe视频或iframe内容。

目前,您可以在iframe代码中的视频URL中添加rel=0参数。根据YouTube文档,rel=0参数将在2019年9月25日后停用

以下是带有rel=0参数的示例:

<iframe width="560" height="315" src="https://www.youtube.com/embed/J8Rt6HSzrqY&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

您还可以使用播放列表功能或参数。以下是示例:

<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?list=PLx0sYbCqOb8TBPRdmBHs5Iftvv9TPboYG&rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

以上代码摘自官方YouTube支持文档。您可以将仅一个视频添加到列表中,以便在当前视频结束后不播放任何其他视频。

它在2018年9月25日被禁用,正如我在问题中所述。它不再禁用相关视频,而是从同一频道显示它们。 - Luis Fernandez
抱歉,我再次检查后发现日期中遗漏了年份。我会寻找另一种解决方案并在这里更新。 - Optimum Creative

0

基于Maximillian Laumeister的工作hideyt,我编写了一个JS文件,可以在任何地方包含,并自动将其魔力包装在您拥有的每个嵌入式YouTube iframe周围。

hideYTrel.js

"use strict";
if (document.readyState !== 'loading') init();
else document.addEventListener('DOMContentLoaded', init);

function init() {
    if (window.runOnce) return;

    if (typeof YT === 'undefined') {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }

    var iframes = [];
    
    for (var iframe of document.querySelectorAll("iframe[src]")) {
        var src = iframe.getAttribute("src");
        if (src.includes("youtube.com/embed/")) {
            if(!src.includes("enablejsapi=1"))
                if(src.includes("?"))
                    iframe.setAttribute("src", src + "&enablejsapi=1");
                else
                    iframe.setAttribute("src", src + "?enablejsapi=1");

            iframes.push(iframe);
        }
    }

    var overlayStyles = {
        display: "none",
        content:"",
        position: "absolute",
        left: 0,
        right: 0,
        cursor: "pointer",
        backgroundColor: "black",
        backgroundRepeat: "no-repeat",
        backgroundPosition: "center",
    };

    window.onYouTubeIframeAPIReady = function() {
        iframes.forEach(function(iframe) {
            var overlay = document.createElement('div');
            for (var style in overlayStyles) {
                overlay.style[style] = overlayStyles[style];
            }
            
            var wrapper = document.createElement('div');
            wrapper.style.display = "inline-block";
            wrapper.style.position = "relative";

            iframe.parentNode.insertBefore(wrapper, iframe);
            
            wrapper.appendChild(overlay);
            wrapper.appendChild(iframe);
            
            var onPlayerStateChange = function(event) {
                if (event.data == YT.PlayerState.ENDED) {
                    overlay.style.backgroundImage = "url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==)";
                    overlay.style.backgroundSize = "64px 64px";
                    overlay.style.top = 0;
                    overlay.style.bottom = 0;
                    overlay.style.display = "inline-block";
                } else if (event.data == YT.PlayerState.PAUSED) {
                    overlay.style.backgroundImage = "url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSIxNzA2LjY2NyIgaGVpZ2h0PSIxNzA2LjY2NyIgdmlld0JveD0iMCAwIDEyODAgMTI4MCI+PHBhdGggZD0iTTE1Ny42MzUgMi45ODRMMTI2MC45NzkgNjQwIDE1Ny42MzUgMTI3Ny4wMTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+)";
                    overlay.style.backgroundSize = "40px 40px";
                    overlay.style.top = "40px";
                    overlay.style.bottom = "50px";
                    overlay.style.display = "inline-block";
                } else if (event.data == YT.PlayerState.PLAYING) {
                    overlay.style.display = "none";
                }
            };
            
            var player  = new YT.Player(iframe, {
                    events: {
                        'onStateChange': onPlayerStateChange
                    }
                });
        
            wrapper.addEventListener("click", function() {
                var playerState = player.getPlayerState();
                if (playerState == YT.PlayerState.ENDED) {
                    player.seekTo(0);
                } else if (playerState == YT.PlayerState.PAUSED) {
                    player.playVideo();
                }
            });
        });
    };
    window.runOnce = true;
}

Jsfiddle: https://jsfiddle.net/pv75zjoh


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接