使HTML5视频海报与视频本身大小相同

119

有人知道如何调整HTML5视频海报的大小,使其适应视频本身的确切尺寸吗?

这里有一个jsfiddle演示了这个问题:http://jsfiddle.net/zPacg/7/

以下是相关代码:

HTML:

<video controls width="100%" height="100%"  poster="http://www.wpclipart.com/blanks/buttons/glossy_buttons/glossy_button_blank_orange_rectangle.png">
  <source src="http://demo.inwebson.com/html5-video/iceage4.mp4" type="video/mp4" />
  <source src="http://demo.inwebson.com/html5-video/iceage4.ogg" type="video/ogg" />
  <source src="http://demo.inwebson.com/html5-video/iceage4.webm" type="video/webm" />
</video>

CSS:

video{
border:1px solid red;
}​

请注意橙色矩形不会缩放到视频的红色边框。

此外,仅添加以下CSS也无效,因为它会重新调整海报大小:

video[poster]{
height:100%;
width:100%;
}

1
我认为你不能在属性中使用“%”符号;但是将其更改为100并不能解决问题。我敢打赌这是一个-webkit媒体样式。请随意查看它们http://trac.webkit.org/browser/trunk/Source/WebCore/css/mediaControls.css - albert
@albert,谢谢。我在你发的链接中没有看到任何关于“poster”的参考。你能给我展示一下你所说的CSS是什么样子的吗?比如,“-webkit media style”。谢谢。 - tim peterson
这就是我所说的“挑选”的意思;那些是Chrome特定的媒体样式;我只有一点点了解它们,更不用说它们声明的伪选择器了;没有起点:我会查找具有填充等声明的内容。 - albert
15个回答

106

根据你的目标浏览器,你可以使用object-fit属性来解决这个问题:

object-fit: cover;

或者也许您正在寻找fill。在IE中仍然在考虑中


3
这绝对是答案。 - cilphex
2
+1 链接到 object-fit 属性,使用 object-fit: initial 对我很有帮助。 - FireBrand
"object-fit: fill"解决了问题!同样有效的是"object-fit: initial"(奇怪的是,在https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit规范中我没有看到"initial"值)。在Android 5.1.1的Samsung原生浏览器中,“cover”和“contain”都会扭曲播放器上的海报。而且这不影响IE! - plugincontainer
2
你们针对什么CSS选择器使用了object-fit规则?由于没有办法针对海报图像进行定位,我猜你们使用了video{object-fit: cover;} - zıəs uɐɟəʇs
2
@zıəs uɐɟəʇs 在我的 CSS 中是这样的... video[poster]{object-fit:fill} - plugincontainer
如果 fit 在不同设备上比 inherit 更好? - Khom Nazid

77
你可以使用透明的海报图片与CSS背景图片结合来实现这一点(示例); 然而,要使背景拉伸到视频的高度和宽度,您将需要使用绝对定位的<img>标签(示例)。
支持background-size的浏览器中,也可以background-size设置为100% 100%(示例)。

更新

更好的方法是使用object-fit CSS属性,正如@Lars Ericsson所建议的那样。

用法

object-fit: cover;

如果您不想显示那些不符合视频纵横比的图像部分,那么
object-fit: fill;

将图像拉伸以适应视频的纵横比

示例


@user1419007,你的示例重复了背景图片。既然你认为这不是最好的方法,能否提供一个 jsfiddle 来演示如何实现你的第二种策略? - tim peterson
2
第二个例子在谷歌浏览器中无法工作?您确实需要像 http://jsfiddle.net/xh8er/ 这样为外部div指定一个位置;然后它就可以工作了。 - commonpike
请参考 Lars Ericsson 的回答,它比这个更好。 - plugincontainer
2
使用此解决方案会在全屏模式下拉伸视频,破坏其宽高比。 - Tengiz
非常有帮助的答案。谢谢。 - Ibra
显示剩余4条评论

27

或者您可以使用preload="none"属性来使视频背景可见。在此处,您可以使用background-size: cover;

 video {
   background: transparent url('video-image.jpg') 50% 50% / cover no-repeat ;
 }

 <video preload="none" controls>
   <source src="movie.mp4" type="video/mp4">
   <source src="movie.ogg" type="video/ogg">
 </video>

2
更好的答案。不会破坏任何东西,而且不预加载视频除非它是一个以视频为中心的站点,否则不会真正影响您的页面。+1。 - totallyNotLizards
1
我在移动设备上进行了背景大小调整。从其他问题/答案中得知(例如https://dev59.com/LnXYa4cB1Zd3GeqP86s1),问题是图像的重复(播放器CSS背景和视频元素海报)。这个修复方法有效。 - plugincontainer
1
嗯...在Chrome中工作正常,但在本机Android浏览器中出现了新问题。请参见:https://stackoverflow.com/questions/39546792/a-cross-browser-fix-for-video-background-image-issues-on-android - plugincontainer
终于修复了 - 请查看下面 Lars Ericsson 的答案。 - plugincontainer

27

我在尝试各种解决方案时进行了实验,最终采用的解决方案是来自于 Google Chrome Inspector 的建议。如果您将以下内容添加到您的 CSS 中,则对我有效:

video{
   object-fit: inherit;
}

谢谢!这正是我寻找的确切解决方法,用于移除顶部和底部的视频间隙。 - cpcdev

13

我的解决方案结合了 user2428118 和 Veiko Jääger 的答案,允许预加载但不需要单独的透明图像。我们使用一个 base64 编码的 1px 透明图像代替。

<style type="text/css" >
    video{
        background: transparent url("poster.jpg") 50% 50% / cover no-repeat ;
    }
</style>
<video controls poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" >
    <source src="movie.mp4" type="video/mp4">
    <source src="movie.ogg" type="video/ogg">
</video>

它只需要图像名称还是完整路径? - user285372
在我的三星手机上的Android原生浏览器(浏览器名为“Internet”),海报在播放时被调整大小...灾难性地。这个解决方案 - 一个透明的gif作为海报,而“poster”作为背景 - 解决了这个问题,但是,现在海报在IE-9、10或11中不显示。 - plugincontainer
1
解决方案是放弃透明gif和以海报为背景的方式,使用(参见上面Lars Ericsson的答案)video [poster] {object-fit:fill}。在Android 5.1.1下的三星原生浏览器上解决了问题,IE显示没有问题。 - plugincontainer
这种方法特别适用于移动设备。object-fit 无法防止在 Android 上内容仍在加载时发生的 poster 的野生尺寸扭曲。 - HolyResistance

8
<video src="videofile.webm" poster="posterimage.jpg" controls preload="metadata">
    Sorry, your browser doesn't support embedded videos.
</video>

封面

video{
   object-fit: cover; /*to cover all the box*/
}

填充

video{
   object-fit: fill; /*to add black content at top and bottom*/
   object-position: 0 -14px; /* to center our image*/
}

请注意,视频控件会覆盖在我们的图片上,因此我们的图片无法完全显示。如果您正在使用 object-fit: cover,请使用像 Photoshop 这样的视觉应用程序编辑您的图像,并添加一个 margin-bottom 内容。

6
我想到了这个主意,它完美地实现了。基本上,我们想要从显示中去掉视频的第一帧,然后将海报调整为视频的实际大小。如果我们设置了尺寸,我们就完成了其中的一个任务。然后只剩下一个任务了。现在,我知道去掉第一帧的唯一方法是实际定义一个海报。但是,我们将给视频一个虚假的海报,一个不存在的海报。这将导致一个空白的显示,背景透明。也就是说,我们父级div的背景将可见。
使用起来很简单,但如果您想将div的背景尺寸调整为视频的尺寸,则可能无法与所有Web浏览器一起使用,因为我的代码正在使用“background-size”。
HTML / HTML5:
<div class="video_poster">
    <video poster="dasdsadsakaslmklda.jpg" controls>
        <source src="videos/myvideo.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
<div>

CSS(层叠样式表):
video{
    width:694px;
    height:390px;
}
.video_poster{
    width:694px;
    height:390px;
    background-size:694px 390px;
    background-image:url(images/myvideo_poster.jpg);
}

很聪明,我试了一下。还不完美,但已经接近了...http://jsfiddle.net/trpeters1/NJtc9/ - tim peterson
是的,你说得对。通过查看你的jsfiddle,我现在意识到视频的尺寸也必须正确,而不仅仅是视频元素。我想当我在我的页面上尝试时,我只是幸运而已。 - Jonathan J

2
我认为实现完全响应式视频的最佳方法是使用css aspect-ratio
下面是一个例子,其中海报比本地视频源高得多。
通过将视频宽度设置为100%,高度:auto,计算出的高度将遵循指定的纵横比。
当与object-fit:cover结合使用时,海报图像受到视频元素计算出的高度/宽度的限制。
然后,您可以选择使用object-position来定位海报。
注意1:我仅出于可读性而使用了css变量。它们对应于视频源的本机高度/宽度。
注意2:使用aspect-ratio的另一个优点是,浏览器可以布局页面元素并在实际加载视频元数据之前保留视频的房地产。这避免了浏览器重新布局惩罚和较少的“内容跳跃”,这对用户更好。
注意3:抱歉,似乎safari一旦加载了视频就隐藏了海报。

video {
  --video-width: 426;
  --video-height: 240;
  aspect-ratio: var(--video-width) / var(--video-height);
  width: 100%;
  height: auto;
  object-fit: cover;
}
<video controls poster="https://media.newyorker.com/photos/5c5349189922c254df56d625/master/pass/Syme-Irving-Penn.jpg">
  <source src="https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4" type="video/mp4">
</video>


2
无需额外的div。
HTML:
<video controls width="100%" height="100%"  poster="http://www.wpclipart.com/blanks/buttons/glossy_buttons/glossy_button_blank_orange_rectangle.png">
  <source src="https://mathisart.org/vid0000_plandemic.mp4" type="video/mp4" />
  <source src="https://mathisart.org/vid0000_plandemic.ogg" type="video/ogg" />
  <source src="https://mathisart.org/vid0000_plandemic.webm" type="video/webm" />
</video>​

CSS:

video[poster]{ object-fit:cover; }  /* or object-fit:fill */

2
你可以使用海报来在移动设备上展示图片,而不是视频(或不支持视频自动播放功能的设备)。因为移动设备不支持视频自动播放功能。
<div id="wrap_video">
<video preload="preload" id="Video" autoplay="autoplay" loop="loop" poster="default.jpg">
<source src="Videos.mp4" type="video/mp4">
Your browser does not support the <code>video</code> tag.
</video>
</div>

现在您可以通过媒体查询仅对移动设备内的视频标签中的海报属性进行样式设置。请注意保留HTML标签。
#wrap_video
{
width:480px;
height:360px;
position: relative;
} 
@media (min-width:360px) and (max-width:780px)
{
video[poster]
{
top:0 !important;
left:0 !important;
width:480px !important;
height:360px !important;
position: absolute !important;
}
}

实际上,iOS 10+支持使用playsinline属性的视频自动播放功能。 - Lukas Petr
你如何指定那个属性? - Khom Nazid

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