62

我想知道是否有任何直接的方法可以实现这种效果,而无需后端代码来提取帧,将其保存为 jpg 并将其数据库化。

当视频加载时视频的第一帧仅显示为海报的效果非常有用(只有在浏览器可以明显播放视频时才有效,这可能与poster传统的工作方式略有不同,但是这不是问题。

4

7 回答 7

84

Did you try the following?

just append time in seconds #t={seconds} to source URL:

  <video controls width="360">
    <source src="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_1MB.mp4#t=0.1" type="video/mp4" />
  </video>

I have chosen a fraction of second (0.1) to keep number of frames small, because I have the suspect that if you put 1 second, it would "preload" the first 1 second of video (i.e. 24 frames or more ....). Just in case ...

Works fine on Chrome and Firefox on desktop :)
Works not on Android mobile, though :(
I did not test on iOS, iPhone, IE yet ??

Edit May 2021:

I realized that many modern browsers now show automatically a poster of first frame.

Seems like they heard us :-)

于 2018-05-17T07:53:35.000 回答
35

To make it simple you can just add preload="metadata" to your video tag and the second of the first frame #t=0.5 to your video source:

<video width="400" controls="controls" preload="metadata">
  <source src="https://www.w3schools.com/html/mov_bbb.mp4#t=0.5" type="video/mp4">
</video>

Best of luck!

于 2018-11-06T13:40:12.313 回答
23

有一个名为Popcorn.capture的Popcorn.js插件,它允许您从 HTML5 视频的任何帧创建海报。

浏览器施加了一个限制,禁止读取跨域请求的资源的像素数据(使用画布 API 记录帧的当前值)。源视频必须托管在与请求它的脚本和 html 页面相同的域中,以便此方法起作用。

使用此插件创建海报的代码非常简单:

// This block of code must be run _after_ the DOM is ready
// This will capture the frame at the 10th second and create a poster
var video = Popcorn( "#video-id" );

// Once the video has loaded into memory, we can capture the poster
video.listen( "canplayall", function() {

  this.currentTime( 10 ).capture();

});
于 2011-09-06T16:34:10.067 回答
17

我最近为一个在桌面和移动设备上工作的最近项目做了这个。诀窍是让它在 iPhone 上运行。

设置preload=metadata适用于台式机和安卓设备,但不适用于 iPhone。

For iPhones I had to set it to autoplay so the poster image automatically appears on initial load. iPhones will prevent the video from auto playing, but the poster image appears as the result.

I had to do a check for iPhone using Pavan's answer found here. Detect iPhone Browser. Then use the proper video tag with or without autoplay depending on the device.

var agent = navigator.userAgent;
var isIphone = ((agent.indexOf('iPhone') != -1) || (agent.indexOf('iPod') != -1)) ;

$videoTag = "";
if(isIphone()) {
    $videoTag = '<video controls autoplay preload="metadata">';
} else {
    $videoTag = '<video controls preload="metadata">';
}
于 2016-08-30T15:36:47.413 回答
8

您可以preload='auto'在视频元素上设置自动加载视频的第一帧。

于 2016-08-23T14:33:26.770 回答
3

Solution for #2, #3 etc. frames. We need attach disposable handler .one() for resetting default frame.

<video width="300" height="150" id='my-video'>
   <source src="testvideo.mp4#t=2" type="video/mp4" />
</video>

$(function () {
     let videoJs = videojs('my-video');
     videoJs.one('play', function () {
          this.currentTime(0);
     });
});
于 2019-02-13T08:17:13.070 回答
0

I found a great way to dynamically add poster to a video!

To show the desired frame from video (in my case it's the frame at 1.75 seconds) - add preload="metadata" to the video element and #t=1.75 to the end of source URL.

Add eventListener to the video element that will listen for play event only once. Once the event is emitted reset the video time.

<video width="100%" controls="controls" preload="metadata" id="myVid">
    <source src="path/to/your/video#t=1.75" type="video/mp4">
</video>

<script>
    var el = document.getElementById('myVid');
    el.addEventListener('play', () => {
        el.currentTime = 0;
    }, { once: true });
</script>
于 2022-02-10T18:06:54.260 回答