ScreenshotNeo

BlogHow-to

How to Preview HTML5 Video in a Web Page

Embed a playable HTML5 video with a poster, responsive sizing, captions, fallbacks, troubleshooting, and a ScreenshotNeo capture option.

By the ScreenshotNeo team1 October 20266 min read

Use the HTML <video> element for a playable preview and its poster attribute for a still image shown before video data is available. Add multiple sources, native controls, a fallback link, captions, and a deliberate preload policy.

<video controls width="640" height="360" poster="/media/clip-preview.jpg" preload="metadata" playsinline>
  <source src="/media/clip.webm" type="video/webm">
  <source src="/media/clip.mp4" type="video/mp4">
  <track kind="captions" src="/media/clip.en.vtt" srclang="en" label="English">
  <p>Your browser does not support embedded video. <a href="/media/clip.mp4">Open the video file</a>.</p>
</video>

controls enables pause, seeking and volume controls. poster references a still image; it does not generate an animated preview. The browser tries each <source> in order.

1. Build a complete HTML5 video preview

Create an HTML page and change the media paths to files on your server or CDN.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Video preview</title>
  <style>
    .video-wrap { max-width: 800px; margin: 2rem auto; }
    video { display: block; width: 100%; height: auto; background: #111; }
  </style>
</head>
<body>
  <main class="video-wrap">
    <h1>Product demo</h1>
    <video controls preload="metadata" poster="/media/demo-poster.jpg" playsinline>
      <source src="/media/demo.webm" type="video/webm">
      <source src="/media/demo.mp4" type="video/mp4">
      <track kind="captions" src="/media/demo.en.vtt" srclang="en" label="English" default>
      <p>Playback is unavailable. <a href="/media/demo.mp4">Download the MP4</a>.</p>
    </video>
  </main>
</body>
</html>

Use width/height or responsive CSS to reserve the correct aspect ratio and reduce layout movement. object-fit: contain preserves the full frame; cover fills the box and may crop it.

2. Choose between a playable preview and a poster

Goal Markup Result
Play inline <video controls> Native player with pause, seeking and volume.
Show a still before playback <video poster="..."> One image while video data is unavailable.
Start from a custom thumbnail Poster plus JavaScript Your button can call video.play().

A poster is the reliable declarative thumbnail. To make a button start playback:

<button type="button" id="play-video">Play video</button>
<video id="demo" controls poster="/media/demo-poster.jpg" preload="none">
  <source src="/media/demo.mp4" type="video/mp4">
</video>
<script>
const video = document.querySelector('#demo');
document.querySelector('#play-video').addEventListener('click', async () => {
  try { await video.play(); } catch (error) { console.error('Playback was blocked', error); }
});
</script>

3. Configure sources, loading and playback

Multiple formats

Container and codec support varies by browser and device. Provide alternate <source> entries and a direct fallback link. The browser uses the first source it can play.

Preload

  • none asks the browser not to preload media.
  • metadata asks for duration and metadata without downloading the whole file up front.
  • auto allows broader preloading when the browser decides it is useful.

preload is only a hint; defaults differ, and autoplay can take precedence. Use metadata for video lists and none when bandwidth matters.

Autoplay and inline playback

autoplay is Boolean: autoplay="false" still enables it. Browsers commonly block audible autoplay. Start from a user gesture or, where appropriate, use muted autoplay playsinline. playsinline asks compatible devices to keep playback inside the element.

Captions

Use WebVTT with <track kind="captions">, supplying srclang, label, and optionally default.

4. Style a responsive preview

.video-frame { aspect-ratio: 16 / 9; max-width: 960px; background: #111; overflow: hidden; }
.video-frame video { width: 100%; height: 100%; object-fit: contain; object-position: center; }
.video-frame.crop video { object-fit: cover; }

Match the poster and video aspect ratios. Use cover only when intentional cropping is acceptable.

5. Add custom controls with the media API

Omit controls only when you provide equivalent keyboard-accessible controls. The HTMLMediaElement API exposes play(), pause(), currentTime, duration, volume, and events such as timeupdate and ended.

<video id="player" poster="/media/poster.jpg" preload="metadata">
  <source src="/media/clip.mp4" type="video/mp4">
</video>
<button id="toggle" type="button" aria-controls="player">Play</button>
<script>
const player = document.querySelector('#player');
const toggle = document.querySelector('#toggle');
toggle.addEventListener('click', async () => {
  if (player.paused) { try { await player.play(); } catch (e) { console.error(e); } }
  else player.pause();
});
player.addEventListener('play', () => { toggle.textContent = 'Pause'; });
player.addEventListener('pause', () => { toggle.textContent = 'Play'; });
</script>

6. Troubleshoot common failures

Symptom Cause Fix
Poster is blank Bad URL, blocked request, or unsupported image. Open the URL directly, inspect the network panel, and serve a valid image with the correct content type.
Video never starts All sources failed, codec mismatch, or network error. Verify URLs and MIME types, inspect the media error, and provide another source.
Controls are missing controls is absent or removed. Add the Boolean attribute. controls="false" still enables it.
Autoplay is ignored Audible autoplay is blocked. Start after a user gesture or use muted inline playback where suitable.
Video is cropped object-fit: cover or mismatched ratios. Use contain or align the frame and media ratios.
Captions do not appear Invalid WebVTT, wrong path, or missing metadata. Validate the VTT file and set srclang/label.
Fallback text does not appear Fallback HTML mainly serves browsers without <video>. Listen for the error event and show a separate error state with a download link.

7. Performance and reliability checklist

  • Use a poster sized for its display slot and an efficient image format.
  • Prefer preload="metadata" or none on pages with many videos.
  • Serve media over HTTPS with stable URLs and correct Content-Type headers.
  • Align poster and video aspect ratios.
  • Test every source on the browsers and devices your project supports.
  • Provide a download or open-file link when playback fails.
  • Use captions and visible keyboard focus for custom controls.

8. Capture a rendered video page with ScreenshotNeo

For a static image of the rendered page, ScreenshotNeo captures the poster and layout after the page loads. It returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API docs for options.

Or skip the browser setup

Capture the page containing your video poster with one request:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/video-page -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/video-page"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/video-page' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);

Cookie banners, newsletter popups and chat widgets are removed before capture. Bot checks, blank pages and failed loads are never billed, and response headers report the verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.

Create a free ScreenshotNeo account.

9. FAQ

Does poster generate a thumbnail?

No. It references a separate still image.

Can I use only one source?

Yes, when its container and codec cover your target browsers. Multiple sources provide fallback coverage.

Why does preload="auto" not always download immediately?

Preload is a browser hint affected by network conditions and user settings.

How do I make a poster clickable?

Add a button or click handler that calls video.play(); the poster attribute alone does not define custom click behavior.