更换 通过视频

问题描述 投票:-1回答:1

我有一个SVG,它有一个简化的结构:

 <svg viewbox="0 0 1000 2000">
   <image width="1024" height="2048" transform="<matrix A>" … />
 </svg>

我想用html5 qazxsw poi元素替换图像,使用qazxsw poi如下:

<video>

因此我有这个代码:

<foreignObject>

基本上到目前为止一切都运行正常,但我不能让<svg viewbox="0 0 1000 2000"> <g transform="<matrix A>"> <foreignObject x="0" y="0" width="100%" height="100%"> <video style="display:block; width: 100%; height: 100%;"> <source src="…" type="…"> </video> </foreignObject> </g> <!-- <image width="1024" height="2048" transform="<matrix in here>" … /> --> </svg> 出现在与图像大小相同的位置。规格说:

(一世)

[...]包含的外国图形内容受SVG转换,过滤,剪裁,屏蔽和合成[...]

(II)

HTML解析器将'foreignObject'中的元素等同于HTML文档片段内的元素。 [...]

考虑(I):通过用从图像复制的所有变换的 [...document.querySelectorAll('image')].forEach(img => { const g = document.createElementNS('…', 'g'), fo = g.appendChild(document.createElementNS('…', 'foreignObject')), video = fo.appendChild(document.createElement('video')), src = video.appendChild(document.createElement('source')) ; g.setAttribute('transform', img.getAttribute('transform')); fo.setAttribute('x', 0); fo.setAttribute('y', 0); fo.setAttribute('width', '100%'); fo.setAttribute('height', '100%'); video.style.cssText = ` position: absolute; top: 100px; left: 100px; background-color: #00ff00; ` video.setAttribute('width', 100); video.setAttribute('height', 100); img.parentNode.appendChild(g); img.parentNode.removeChild(img); }); 替换图像,视频应该“生活在坐标空间”中。

考虑到(II),<video>应该成为新文档片段的根节点,并且适合给定区域。

但结果看起来像这样:

<g>

其中:黑色区域代表整个SVG,白色区域代表整个HTML文档,其中包括SVG。两个绿色区域都是/ seam是视频,其中较大的一个是我想要的视频。

为什么/我错过了什么?

UPDATE

由于这太过分了,我创建了这个基本的svg:

<video>

什么在Firefox中完美运行,但在Chromium中没有。我可以设法通过在视频中添加enter image description here来播放视频,但<svg width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"> <defs> <clipPath id="clip"> <circle cx="100" cy="100" r="100" /> </clipPath> </defs> <rect x="0" y="0" width="200" height="200" style="fill:#ff0000;stroke:none" clip-path="url(#clip)" /> <g clip-path="url(#clip)"> <foreignObject x="0" y="0" width="200" height="200" > <video autoplay="" width="100%" height="100%"> <source src="/path/to/a/video.mp4" type="video/mp4" /> </video> </foreignObject> </g> <text x="100" y="100">Hello</text> </svg> 不会出现在视频前面,以铬为单位。

考虑到视频的坐标,这有效:

style="clip-path: url(#clip)"
javascript html5 svg
1个回答
-1
投票

您的视口是1000x2000,但图像是1024x2048。我认为这会剪辑你的形象。可能是混乱的一部分。

下一页:图像比视频更自由缩放,因为您通常希望保留视频的宽高比。这就是为什么当视频大小不适合容器时你会出现黑色边框。确保视频大小,图像大小和SVG视口都一致。

我也有点怀疑浏览器可以将所有SVG转换应用于视频。至少在过去,浏览器不会自己渲染视频,而是在页面中保留矩形区域,并将该区域的坐标发送到视频渲染器(可以使用覆盖窗口在另一个进程中)。如果您无法使用此功能,请尝试将整个SVG替换为视频。

此外,不是在JavaScript中执行此操作,而是构建一个小的本地HTML文件,您可以快速调整,直到视频看起来正确。当它工作时,然后从可以在两者之间转换的代码开始。否则,你会打开太多的蠕虫。

[更新1]

欢迎来到地狱。停留片刻 ...

您可以尝试使用开发人员工具来了解Chromium在这种情况下正在做什么。也许创建第二个本地测试用例,你尝试在视频上放置带有一些文本的<text>。如果这不起作用,那么Chromium正在为这种类型的视频使用外部渲染器。

这在屏幕上看起来是一样的,但在幕后,Chromium要求另一个进程在屏幕上放置另一个窗口,使其看起来好像是页面的一部分。如果您有一个工具可以显示屏幕上所有应用程序窗口的坐标,您可以看到有一个工具停留在浏览器窗口的顶部。点击进入该窗口,Chromium无法看到它们,并且它无法在该窗口前面呈现任何内容,因为它是其他人的窗口(就像您不希望Chromium在文本编辑器上呈现恰好是通过浏览器窗口打开)。

选项:

  1. 转换为Chromium可以自行呈现的格式。请参阅const { top, left, width, height } = foreignObject.getBoundingClientRect() ; Object.entries({ width, height}).forEach( ([k,v]) => video.setAttribute(k,v) ); video.style.left = `${left}px`; video.style.top = `${top}px`; 以获取列表。那可能只是VP8,VP9和Theora(=任何“开放”视频格式)。 H.264和MPEG-4可能不起作用,因为电影制片厂恐慌你可以窃取他们的宝贵。
  2. 在文本覆盖的位置使用文本覆盖,并将文本移动到视频下方的文本中。
  3. 在提供视频文件的服务器上使用进程将文本标记到视频中,然后再将其传递给浏览器。有些视频格式支持字幕,如果您不需要任何太多花哨的话,可能会滥用这些字幕。这将防止重新编码视频的需要。
  4. 显示文本并要求访问者安装浏览器。
© www.soinside.com 2019 - 2024. All rights reserved.