在 HTML5 视频中动态使用第一帧作为海报?

发布于 2024-12-03 17:26:20 字数 158 浏览 2 评论 0 原文

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

当视频加载时,视频的第一帧只显示为海报的效果会非常有用(只有当浏览器可以明显地播放视频时它才会起作用,这可能与海报的方式有点不同)传统上是可行的,但这不是一个问题。

I'm wondering if there's any straightforward way to achieve this effect, without needing backend code to extract a frame, save it as a jpg and database it somewhere.

An effect whereby the first frame of the video just shows up as the poster when the video loads would be so helpful (it would only work if the browser can play back the video obviously, which might be a little different from how poster traditionally works, but that is not a concern.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

你的往事 2024-12-10 17:26:20

您尝试过以下操作吗?

只需将时间(以秒为单位)#t={seconds} 附加到源 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>

我选择了秒的一小部分(0.1)来保持较小的帧数,因为我怀疑如果你放置1秒,它会“预加载”第一个1 秒的视频(即 24 帧或更多......)。以防万一...

在桌面版 Chrome 和 Firefox 上运行良好:)
不过,不适用于 Android 手机:(
我还没有在 iOS、iPhone、IE 上测试过??

2021 年 5 月编辑:

我意识到许多现代浏览器现在会自动显示第一帧的海报。

看起来他们听到了我们的声音:-)

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 :-)

甜心小果奶 2024-12-10 17:26:20

为了简单起见,您只需将 preload="metadata" 添加到您的视频标记,并将第一帧的第二个 #t=0.5 添加到您的视频来源

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

祝你好运!

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!

一身骄傲 2024-12-10 17:26:20

有一个名为 Popcorn.js 插件rel="noreferrer">Popcorn.capture 允许您从 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();

});

There is a Popcorn.js plugin called Popcorn.capture which will allow you to create posters from any frame of your HTML5 video.

There is a limitation that is imposed by the browser that prohibits reading pixel data of resources requested across domains (using the canvas API to record the current value of a frame). The source video must be hosted on the same domain as the script and html page that is requesting it for this approach to work.

The code to create poster using this plugin is quite simple:

// 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();

});
酒绊 2024-12-10 17:26:20

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

设置 preload=metadata 适用于桌面和 Android 设备,但不适用于 iPhone。

对于 iPhone,我必须将其设置为自动播放,以便海报图像在初始加载时自动显示。 iPhone 会阻止视频自动播放,但结果会显示海报图像。

我必须使用此处找到的 Pavan 答案对 iPhone 进行检查。 检测 iPhone 浏览器。然后根据设备使用带或不带自动播放的正确视频标签。

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">';
}

I recently did this for a recent project that works on desktop and mobile. The trick was getting it to work on iPhone.

Setting preload=metadata works on desktop and android devices but not 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">';
}
仲春光 2024-12-10 17:26:20

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

You can set preload='auto' on the video element to load the first frame of the video automatically.

萌化 2024-12-10 17:26:20

#2、#3 等帧的解决方案。我们需要附加一次性处理程序 .one() 来重置默认框架。

<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);
     });
});

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);
     });
});
不必了 2024-12-10 17:26:20

我找到了一种将海报动态添加到视频的好方法!

要显示视频中所需的帧(在我的例子中是 1.75 秒的帧) - 将 preload="metadata" 添加到视频元素,并将 #t=1.75 添加到源 URL 末尾。

将 eventListener 添加到视频元素,该元素仅侦听一次 play 事件。
事件发出后重置视频时间。

<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>

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>
听不够的曲调 2024-12-10 17:26:20

对于其他想要将图像指定为海报的人,请使用海报属性

<video src="/path/to/video.mp4" poster="/path/to/poster.png"></video>

For others, who wants to specify image as poster, use poster attribute:

<video src="/path/to/video.mp4" poster="/path/to/poster.png"></video>
坦然微笑 2024-12-10 17:26:20

虽然现在第一帧通常会自动加载(至少在使用 preload="metadata" 时),但这似乎在某些移动场景中不起作用,例如在带有 Cordova 的 Android WebView 中。 (另请参阅此问题。)

我对此特别的解决方案是添加一个autoplay 属性和 play 上执行 .pause() 的一次性事件侦听器:

<video preload="metadata" autoplay>
  <!-- ... -->
</video>
myVideo.addEventListener('play', () => myVideo.pause(), { once: true })

While nowadays the first frame is usually loaded automatically anyway (at least when using preload="metadata"), this doesn't seem to work in some mobile scenarios, such as within a WebView an Android with Cordova. (See also this issue.)

My solution for this special was to add an autoplay attribute and a one-time event listener on play that does .pause():

<video preload="metadata" autoplay>
  <!-- ... -->
</video>
myVideo.addEventListener('play', () => myVideo.pause(), { once: true })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文