skip to Main Content

I have a web application build on NextJS. I intend to use a transparent video, which currently I have as MOV and WEBP, WEBP works absolutely fine on Chrome (Desktop), while MOV works fine on Safari (Desktop). But I am facing issues when it come to Chrome (IOS), Chrome (Android) has no issues. However Chrome (IOS) does not show the alpha channels, it shows a while background. How can I fix this? what is the best approach for this, or is there any other file type that I should use?

2

Answers


  1. There are multiple approaches to this.

    The first option is to use a different video format. You speak of using webP, but have a look at VP9/WebM. Have a look at its possible implementation. Google itself also speaks on the uses and shortcomings of webP.

    As a second option, as some commenters already mentioned, one way is to have two videos. One being the mask and one to have the colors. For that, you can see the following example that uses the HTML canvas.

    Important Note: Please click the ‘full page’ button to properly see the snippet in action. Else, scroll down after pressing p to play.

    Credit: Nathan Searles

    const width = 640;
    const height = 450;
    let videoPlaying = false;
    let processControl;
    
    // Main video
    const canvas_video = document.getElementById('canvas_video');
    const video_ctx = canvas_video.getContext('2d');
    const video = document.getElementById('video');
    video.crossOrigin = 'Anonymous';
    video_ctx.canvas.width = width;
    video_ctx.canvas.height = height;
    
    // Mask
    const canvas_mask = document.getElementById('canvas_mask');
    const mask_ctx = canvas_mask.getContext('2d');
    const mask = document.getElementById('mask');
    mask.crossOrigin = 'Anonymous';
    mask_ctx.canvas.width = width;
    mask_ctx.canvas.height = height;
    
    // Output canvas
    const output = document.getElementById('output');
    const output_ctx = output.getContext('2d');
    output_ctx.canvas.width = width;
    output_ctx.canvas.height = height;
    output.crossOrigin = 'Anonymous';
    
    function Process() {
      processControl = window.requestAnimationFrame(Process);
    
      video_ctx.drawImage(video, 0, 0, width, height);
      mask_ctx.drawImage(mask, 0, 0, width, height);
    
      // getImageData
      // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData
      const image = video_ctx.getImageData(0, 0, width, height);
      const imageData = image.data;
    
      const maskData = mask_ctx.getImageData(0, 0, width, height).data;
    
      for (let i = 3, len = imageData.length; i < len; i = i + 4) {
        imageData[i] = maskData[i-1];
      }
    
      output_ctx.putImageData(image, 0, 0, 0, 0, width, height);
    }
    
    document.body.onkeyup = function(e){
      if(e.keyCode === 80){
        if (videoPlaying) {
          mask.pause();
          video.pause();
          videoPlaying = false;
          cancelAnimationFrame(processControl);
        } else {
          mask.play();
          video.play();
          Process();
          videoPlaying = true;
        }
      }
    }
    /*
      Background pattern:
      
    Home
    */ body { font-family: sans-serif; font-weight: 600; background-color: #5353; background-image: background-color: #ee5522; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 200 200'%3E%3Cdefs%3E%3ClinearGradient id='a' gradientUnits='userSpaceOnUse' x1='100' y1='33' x2='100' y2='-3'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23000' stop-opacity='1'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='100' y1='135' x2='100' y2='97'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23000' stop-opacity='1'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg fill='%23d23d09' fill-opacity='0.6'%3E%3Crect x='100' width='100' height='100'/%3E%3Crect y='100' width='100' height='100'/%3E%3C/g%3E%3Cg fill-opacity='0.5'%3E%3Cpolygon fill='url(%23a)' points='100 30 0 0 200 0'/%3E%3Cpolygon fill='url(%23b)' points='100 100 0 130 0 100 200 100 200 130'/%3E%3C/g%3E%3C/svg%3E"); text-align: center; } p { margin: 20px 0; padding: 10px 20px; border-radius: 20px; background: rgba(255,255,255,0.95); box-shadow: 10px 10px 10px rgba(0,0,0,0.1); display: inline-block; } canvas { display: none; } #output { display: block; margin: 80px auto; } video { width: 640px; height: auto; }
    <div id="stage">
      <p id="control">Hit "p" to play/pause videos</p>
    
      <!-- Main element -->
      <canvas id="output"></canvas>
    
      <!-- Shown for reference -->
      <canvas id="canvas_video"></canvas>
      <canvas id="canvas_mask"></canvas>
    
      <!-- Hidden with CSS -->
      <video id="mask" src="http://nathansearles.com/videos/knife-mask.mp4" crossorigin="anonymous" loop></video>
      <video id="video" src="http://nathansearles.com/videos/knife.mp4" crossorigin="anonymous" loop></video>
    </div>
    Login or Signup to reply.
  2. To support transparent video on web applications for both desktop and mobile, use the WebM format with VP9 codec and alpha channel. This format is widely supported across modern browsers.

    Implementation Steps
    Create Transparent Video: Export your video in WebM format using VP9 with alpha channel (e.g., with Adobe After Effects).
    Embed in HTML:

    <video autoplay loop muted playsinline>
        <source src="your-video-file.webm" type="video/webm">
        <img src="your-fallback-image.gif" alt="Fallback image">
    </video>
    

    Fallback Solutions: Provide GIF or PNG sequences for browsers like Safari that do not support WebM with VP9.

    Browser Compatibility
    Chrome, Firefox, Edge: Full support on desktop and mobile.

    Safari: Use fallback methods (PNG/GIF).
    This ensures the best transparency support across most browsers.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search