1

我想更改 YouTube 视频的源 swf 文件。视频是一个<embed>元素。

它是如何构建的:

<embed width="640" id="movie_player-flash" height="390"
       tabindex="0" type="application/x-shockwave-flash"
       src="http://s.ytimg.com/yt/swfbin/watch_as3-vfl07wZSq.swf" flasvars="...">

(可以在Google 的 YouTube 频道上找到一个示例)

我遗漏了一些属性和内容,flashvars因为它是一个带有设置的长字符串,这会影响视频吗?


我试过的:

  1. 我尝试通过简单地更改src属性来尝试,但这不会影响任何事情:

    document.getElementById('movie_player-flash').src = url;
    
  2. 我还尝试克隆原始文件,更改源并重新附加它。再说一遍:没有:

    var player = document.getElementById('movie_player-flash');
    var playerClone = player.cloneNode(true);
    playerClone.setAttribute('src', url);
    
    player.parentNode.replaceChild(playerClone, player);
    

有人知道如何完成更改视频源吗?

4

1 回答 1

2

这里有很多问题:

  1. Flash 视频并不总是在<embed id="movie_player-flash",有时它在<embed id="movie_player"。由于这是 Google,因此可能还有其他方案。所以,一个简单document.getElementById('movie_player-flash')的就出来了。使用类似的东西:

    var flashEmbed  = document.querySelectorAll ("#movie_player-flash, #movie_player");
    if (flashEmbed.length) {
        flashEmbed  = flashEmbed[0];
        // DO THE SWITCH HERE.
    }
    


  2. 更改src属性确实有效,但仅在极少数情况下。如果您要切换到其他视频:

    1. 不需要参数。 (尽管您可以通过创建适当的<object><param>标签来恢复这些。)
    2. 不加载外部依赖项。 如果它们与目标页面不在同一个域中,它们将被跨域安全阻止。此外,flash 文件加载的对象的路径通常在文件本身内是固定的(即使是相同的域,也可能给出 404 错误)。

    然后,它可以工作。看到这个小提琴

  3. 回覆:

    我遗漏了一些属性和内容,flashvars因为它是一个带有设置的长字符串,这会影响视频吗?

    在现代 Youtube 上,这flashvars就是一切!此外,如果您比较该src属性,您会发现它对于大多数所有 Flash 视频都是相同的。例如,无论我尝试什么视频,目前src都是http://s.ytimg.com/yt/swfbin/watch_as3-vfl07wZSq.swf.

    这是因为<embed>标签加载的 Flash 对象不是视频。它是一个加载播放器(和其他东西)的外壳对象,播放器加载实际的视频文件。

    因此,名义上,要将一个 Youtube 视频更改为另一个,您必须更改参数和/或flashvars. 即使您将 更改src为旧式的直接<embed>链接 (EG: http://www.youtube.com/v/uY3LAFJbKyY?version=3&amp;hl=en_US&amp;rel=0),它也只会在按下Play按钮之前似乎有效。然后参数中定义的视频将返回并播放。

  4. 但是, Youtube 仍然保留了旧系统的某些方面(目前)。因此,如果您能找到旧式嵌入链接,您可以将 换成src那个并用<embed>没有flashvars. 请参阅答案末尾的代码。

    这是查找旧式嵌入链接的一种方法:

    1. 在视频的 Youtube 页面上,按下分享按钮
    2. 嵌入按钮
    3. 选中使用旧嵌入代码复选框
    4. 文本区域现在将显示<object>...<embed>...HTML。将其复制并仅提取<embed> src属性。(例如:

      http://www.youtube.com/v/uY3LAFJbKyY?version=3&amp;hl=en_US&amp;rel=0
      

      )
      丢弃一切。

  5. flash 元素并不总是立即加载。它也可以通过 AJAX 替换。所以,我们可能需要等待(右)<embed>出现。
    为简单起见,我将使用 来展示这一点setInterval(),但对于一个强大、实用的解决方案,您将需要使用waitForKeyElements()实用程序,如本答案所示。


综上所述,这是一个完整的 Greasemonkey 脚本,可以替换大多数视频:

// ==UserScript==
// @name        _Youtube, replace flash video
// @description Replaces most videos with the Greatest Video Of All Time!
// @include     http://www.youtube.com/watch*
// @include     http://www.youtube.com/user*
// @grant       none
// ==/UserScript==

var embedChkIntval  = setInterval ( function () {
        var flashEmbed  = document.querySelectorAll ("#movie_player-flash, #movie_player");
        if (flashEmbed.length) {
            var playerClone = flashEmbed[0].cloneNode (true);
            playerClone.src = 'http://www.youtube.com/v/dQw4w9WgXcQ?version=3&amp;hl=en_US&amp;rel=0';
            playerClone.removeAttribute ("flashvars");

            flashEmbed[0].parentNode.replaceChild (playerClone, flashEmbed[0]);
            clearInterval (embedChkIntval);
        }
    },
    150
);
于 2012-09-17T06:01:06.693 回答